0.导语

本节为手撕代码系列之第一弹,主要来手撕排序算法,主要包括以下几大排序算法:

  • 直接插入排序

  • 冒泡排序

  • 选择排序

  • 快速排序

  • 希尔排序

  • 堆排序

  • 归并排序

1.直接插入排序

算法思想

每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。

代码实现

  1. # 直接插入排序
  2. def insert_sort(arr):
  3. length = len(arr)
  4. for i in range(length):
  5. k = i
  6. for j in range(k,0,-1):
  7. if arr[j]<arr[j-1]:
  8. t = arr[j]
  9. arr[j]=arr[j-1]
  10. arr[j-1]=t
  11. arr = [4,3,0,-1]
  12. insert_sort(arr)
  13. print(arr)

2.冒泡排序

算法思想

对相邻的元素进行两两比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。

代码实现

  1. # 冒泡排序
  2. def bubbleSort(arr):
  3. length = len(arr)
  4. for i in range(length-1):
  5. flag = True
  6. for j in range(length-i-1):
  7. if arr[j]>arr[j+1]:
  8. t = arr[j]
  9. arr[j]=arr[j+1]
  10. arr[j+1]=t
  11. flag = False
  12. if flag:
  13. break
  14. arr = [6,-2,0,9]
  15. bubbleSort(arr)
  16. print(arr)

3.选择排序

算法思想

每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,简单选择排序是不稳定排序

代码实现

  1. def selectSort(arr):
  2. length = len(arr)
  3. for i in range(length-1):
  4. min = i
  5. for j in range(i+1,length):
  6. if arr[min]>arr[j]:
  7. min=j
  8. if min!=i:
  9. t = arr[i]
  10. arr[i]=arr[min]
  11. arr[min]=t
  12. arr = [6,-2,0,9]
  13. selectSort(arr)
  14. print(arr)

4.快速排序

算法思想

快速排序思想----分治法。

  • 先从数列中取出一个数作为基准数。

  • 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

  • 再对左右区间重复第二步,直到各区间只有一个数。

每次划分得到,枢椎的左边比它小,右边比它大。

代码实现

方法一(通过遍历直接得到大于pivot和小于pivot的元素):

  1. class Solution:
  2. def quicksort(self, array):
  3. """
  4. :type numRows: int
  5. :rtype: List[List[int]]
  6. """
  7. if len(array)<=1:
  8. return array
  9. else:
  10. pivot=array[0]
  11. small=[i for i in array[1:] if i<=pivot]
  12. big=[i for i in array[1:] if i >pivot]
  13. return self.quicksort(small)+[pivot]+self.quicksort(big) //递归法,耗时

方法二(双指针前后移动):

  1. def quickSort(arr,left,right):
  2. # 递归终止条件
  3. if left>right:
  4. return
  5. pivot = arr[left]
  6. i = left
  7. j = right
  8. while i<j:
  9. while i<j and arr[j]>=pivot:
  10. j-=1
  11. while i<j and arr[i]<=pivot:
  12. i+=1
  13. if i<j:
  14. t = arr[i]
  15. arr[i] = arr[j]
  16. arr[j] = t
  17. # 放入枢椎
  18. arr[left] = arr[i]
  19. arr[i]=pivot
  20. # 递归调用左区域
  21. quickSort(arr,left,i-1)
  22. # 递归调用右区域
  23. quickSort(arr,i+1,right)
  24.  
  25. arr = [6,-2,0,9]
  26. quickSort(arr,0,len(arr)-1)
  27. print(arr)

5.希尔排序

算法思想

该算法也被称为:缩小增量排序

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

代码实现

  1. # 希尔排序
  2. def shellSort(arr):
  3. length = len(arr)
  4. # 设置初始增量
  5. gap = length//2
  6. while gap>0:
  7. # 从第gap个元素,逐个对其所在组进行直接插入排序
  8. for i in range(gap,length):
  9. j = i
  10. while j-gap>=0 and arr[j]<arr[j-gap]:
  11. t = arr[j]
  12. arr[j] = arr[j-gap]
  13. arr[j-gap] = t
  14. j-=gap
  15. gap//=2
  16. arr = [6,-2,0,9]
  17. shellSort(arr)
  18. print(arr)

6.堆排序

算法思想

堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。

基本思路:

  a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;

  b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;(升序方法)

  c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

代码实现

方法1:

  1. class HeapSort:
  2. def heapSort(self, nums):
  3. length = len(nums)
  4. # 从后往前遍历,交换堆顶与最后叶子节点,并依次调整堆,重复操作
  5. for j in range(length-1,0,-1):
  6. # 获取堆顶元素(获取同时,调整堆)
  7. firstNum = self.adjustHeap(nums,j+1)
  8. # 交换最后一个叶子节点与堆顶元素
  9. temp = nums[j]
  10. nums[j] = firstNum
  11. nums[0] = temp
  12. return nums
  13. # 调整堆(最大堆),每次返回最大堆顶元素
  14. def adjustHeap(self,nums,length):
  15. # 最后一个非叶节点
  16. i = length//2 -1
  17. # 从最后一个非叶节点开始调整,构成最大堆
  18. while i>=0:
  19. temp = nums[i]
  20. k = 2*i+1
  21. while k<length:
  22. if k+1<length and nums[k]<nums[k+1]:
  23. k+=1
  24. if nums[k]>temp:
  25. nums[i]=nums[k]
  26. i=k
  27. else:
  28. break
  29. k=2*k+1
  30. nums[i] = temp
  31. i-=1
  32. return nums[0]
  33. s = HeapSort()
  34. nums = [8,9,7,10]
  35. t = s.heapSort(nums)
  36. print(t)

方法2:

  1. def buildMaxHeap(self,arr):
  2. import math
  3. for i in range(math.floor(len(arr) / 2), -1, -1):
  4. self.heapify(arr, i)
  5.  
  6. def heapify(self, arr, i):
  7. left = 2 * i + 1
  8. right = 2 * i + 2
  9. largest = i
  10. if left < arrLen and arr[left] > arr[largest]:
  11. largest = left
  12. if right < arrLen and arr[right] > arr[largest]:
  13. largest = right
  14.  
  15. if largest != i:
  16. self.swap(arr, i, largest)
  17. self.heapify(arr, largest)
  18.  
  19. def swap(self, arr, i, j):
  20. arr[i], arr[j] = arr[j], arr[i]
  21.  
  22. def heapSort(self, arr):
  23. global arrLen
  24. arrLen = len(arr)
  25. self.buildMaxHeap(arr)
  26. for i in range(len(arr) - 1, 0, -1):
  27. self.swap(arr, 0, i)
  28. arrLen -= 1
  29. self.heapify(arr, 0)
  30. return arr

7.归并排序

算法思想

归并排序是利用归并的思想实现的排序方法,该算法采用经典的分治策略(分治法将问题(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

代码实现

  1. import math
  2. class Solution:
  3. def mergeSort(self,arr):
  4. if (len(arr) < 2):
  5. return arr
  6. middle = math.floor(len(arr) / 2)
  7. left, right = arr[0:middle], arr[middle:]
  8. return self.merge(self.mergeSort(left), self.mergeSort(right))
  9.  
  10. def merge(self,left, right):
  11. result = []
  12. while left and right:
  13. if left[0] <= right[0]:
  14. result.append(left.pop(0));
  15. else:
  16. result.append(right.pop(0));
  17. while left:
  18. result.append(left.pop(0));
  19. while right:
  20. result.append(right.pop(0));
  21. return result

来自于wx公众号“光城”。

几种排序算法代码c++版本 (暂无堆排和希尔排序):

  1. #include "../stdafx.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string>
  5. #include <algorithm>
  6. #include <vector>
  7. #include <queue>
  8. #include<functional>
  9. #include <map>
  10. #include <iostream>
  11. using namespace std;
  12.  
  13. void BubbleSort(vector<int> &arr){
  14. if (arr.size() <= )
  15. return;
  16. for (int len = arr.size() - ; len >= ; len--){
  17. for (int i = ; i < len; i++){
  18. if (arr[i]>arr[i + ])
  19. swap(arr[i], arr[i + ]);
  20. }
  21. }
  22. }
  23.  
  24. void SelectionSort(vector<int> &arr){
  25. if (arr.size() <= )
  26. return;
  27. for (int i = ; i < arr.size() - ; i++){
  28. int min_index = i;
  29. for (int j = i + ; j < arr.size(); j++){
  30. /*if (arr[j]<arr[j-1]) //每次左边起始位置向前移一个,但是并不能保证一轮下来,左边的数为最小值
  31. swap(arr[j-1], arr[j]);*/
  32. min_index = arr[min_index] < arr[j] ? min_index : j;
  33. }
  34. swap(arr[min_index],arr[i]);
  35. }
  36. }
  37.  
  38. void InsertSort(vector<int> &arr){
  39. if (arr.size() <= )
  40. return;
  41. for (int i = ; i < arr.size(); i++){ //从索引1开始,前面索引0区域为插入空间
  42. for (int j = i - ; j >= && arr[j]>arr[j + ]; j--) //--逆序(直接和插入空间最右(也即最大)的数比较,就可知是否进行插入)
  43. swap(arr[j], arr[j + ]); //不是i,j直接比较 j--决定插入的具体位置,如(1,3,5)2
  44. }
  45. }
  46.  
  47. void QuickSort(vector<int> &arr,int L, int R){
  48. if (L >= R) //递归终止条件
  49. return;
  50. int pivot = arr[L];
  51. int i = L, j = R;
  52. while (i != j){
  53. //先从右边找,否则会报错
  54. while (arr[j] > pivot&&i < j)
  55. j--;
  56. while (arr[i] <= pivot&&i < j)
  57. i++;
  58. if (i < j){
  59. swap(arr[i],arr[j]);
  60. }
  61. }
  62. arr[L] = arr[i];
  63. arr[i] = pivot; //最终pivot位置为i
  64. QuickSort(arr, L, i - );
  65. QuickSort(arr, i + ,R);
  66. }
  67.  
  68. //归并:先拆分为若干子数组,通过merge()对其逐步合并排序
  69. void Merge(vector<int> &arr, int L, int mid, int R){
  70. int i = L, j = mid + ;
  71. vector<int> new_arr;
  72. while (i <= mid&&j <= R){
  73. if (arr[i] <= arr[j])
  74. new_arr.push_back(arr[i]),i++;
  75. else
  76. new_arr.push_back(arr[j]),j++;
  77. }
  78. while (i <= mid)
  79. new_arr.push_back(arr[i]), i++;
  80. while (j <= R)
  81. new_arr.push_back(arr[j]), j++;
  82. for (int k = L, t = ; k <= R; k++, t++) //把值复制回原arr
  83. arr[k] = new_arr[t];
  84. }
  85.  
  86. void MergeSort(vector<int> &arr, int L, int R){
  87. if (L >= R)
  88. return;
  89. else{
  90. int mid = (L + R) / ;
  91. MergeSort(arr, L, mid);
  92. MergeSort(arr, mid + , R);
  93.  
  94. Merge(arr, L, mid, R);
  95. }
  96. }
  97.  
  98. int main(void){
  99.  
  100. vector<int> array = {, , , , , , , , };
  101. //BubbleSort(array);
  102. //SelectionSort(array);
  103. //InsertSort(array);
  104. //QuickSort(array, 0, array.size() - 1);
  105. MergeSort(array, , array.size() - );
  106. vector<int> vec = array;
  107.  
  108. vector <int>::iterator it;
  109. for (it = vec.begin(); it != vec.end();it++)
  110. cout << *it << endl;
  111.  
  112. getchar();
  113. return ;
  114. }

基本算法复杂度:

参考来源:https://linux.cn/article-7480-1.html

排序代码(python,c++) 及 基本算法复杂度的更多相关文章

  1. 选择排序之python

    选择排序( Selection sort) 1.算法描述: 通过n-i次关键字之间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录进行交换. 对尚未完成排 ...

  2. 具体knn算法概念参考knn代码python实现

    具体knn算法概念参考knn代码python实现上面是参考<机器学习实战>的代码,和knn的思想 # _*_ encoding=utf8 _*_ import numpy as npimp ...

  3. 编程算法 - 切割排序 代码(C)

    切割排序 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 排序切割, 把一个数组分为, 大于k\小于k\等于k的三个部分. 能够使用高速排序的Parti ...

  4. python实现折半查找算法&&归并排序算法

    今天依旧是学算法,前几天在搞bbs项目,界面也很丑,评论功能好像也有BUG.现在不搞了,得学下算法和数据结构,笔试过不了,连面试的机会都没有…… 今天学了折半查找算法,折半查找是蛮简单的,但是归并排序 ...

  5. python拓展3 常用算法

    知识内容: 1.递归复习 2.算法基础概念 3.查找与排序 参考资料: http://python3-cookbook.readthedocs.io/zh_CN/latest/index.html h ...

  6. 八大排序的python实现

    以下是八大排序的python实现,供以后参考,日后扩展 一.插入排序 #-*- coding:utf-8 -*- ''' 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一 ...

  7. 使用python模拟实现KNN算法

    一.KNN简介 1.KNN算法也称为K邻近算法,是数据挖掘分类技术之一.所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表. 2.KNN算法的核心思想是如果一个样本 ...

  8. Python遗传和进化算法框架(一)Geatpy快速入门

    https://blog.csdn.net/qq_33353186/article/details/82014986 Geatpy是一个高性能的Python遗传算法库以及开放式进化算法框架,由华南理工 ...

  9. 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法

    若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ...

随机推荐

  1. ORM对象关系型映射的用法

    ORM对象关系型映射的用法 -- Django模型 1.什么是ORM关系型映射 ORM 全拼Object-Relation Mapping. 中文意为 对象-关系映射. 主要实现模型对象到关系数据库数 ...

  2. redis_ 5 集群

    [转自 ]https://www.cnblogs.com/hjwublog/p/5681700.html#_label0 Redis集群简介 Redis 集群是3.0之后才引入的,在3.0之前,使用哨 ...

  3. botot framework选择下拉框

    1,下拉框不能输入文字,如图: 方法: select from list    id=xxx   要选择的数据 2.下拉框可输入文字,如图: 方法: click element   di=xxx   ...

  4. static类型autowired 注入失败

    原代码:注入commonService对象失败 @Autowired private static CommonService commonService; public static List< ...

  5. BA-siemens-insight-event builder使用

    event builder功能主要是用来给report使用的,作为一个独立的对象,这个对象的功能就是收集点位的信息,如果再使用report功能就可以显示或输出点位的信息.

  6. 【我所认知的BIOS】—&gt; uEFI AHCI Driver(6) AtaAtapiPassThruSupported的局部变量们

    [我所认知的BIOS]-> uEFI AHCI Driver(6) - AtaAtapiPassThruSupported的局部变量们 LightSeed 5/7/2014 前面5个篇文章把EF ...

  7. chrome打开网址但是没有地址栏

    chrome打开网址但是没有地址栏 C:\Users\Administrator>C:\Users\Administrator\AppData\Local\Google\Chrome\Appli ...

  8. 彻底禁用resource manager

    禁用resource manager 由于发现系统的一个等待事件:resmgr:cpu quantum.这是由于resource manager的原因.看来resource manager 的bug还 ...

  9. python2.7编码与解码

    常见的编码 ASCII: 美国人发明的,只编码英文字母和符号,1个字节. GB2312: 中国人发明的,增加了中文汉字和符号,2个字节. Unicode: 为了把所有语言都统一到一套编码里,一般是2个 ...

  10. DatabaseMetaData开发实务

    1.总论 在企业开发实务中,数据迁移是经常会遇到的事情,此时,需要搞清楚,源数据库与目的数据库之间表以及表内部各列之间的异同.而有些时候,我们拿到的项目文 档,未必能准确表述各个表的准确结构,即使应用 ...