排序总结
来源:互联网 发布:旧货市场淘宝 编辑:程序博客网 时间:2024/06/16 16:51
一、 插入排序
1,思想:将第 i 个记录插入到前面 i-1 个已经排序好的序列之中。
2,时间复杂度 O(n^2),空间复杂度 O(1)。
3,稳定性:稳定。
4,过程分析
初始: 34 8 64 51 32 21
第一趟: 8 34 64 51 32 21
第二趟 8 34 64 51 32 21
第三趟 8 34 51 64 32 21
第四趟 8 32 34 51 64 21
第五趟 8 21 32 34 51 64
5,伪码:
void insertionSort(vector<int> A){ for (int i = 1; i < A.size(); ++i){int tmp = A[i];int j = i;for (; j >0 && A[j - 1]>tmp; j--)A[j] = A[j - 1];A[j] = tmp;}}
二、希尔排序
1,思想:将待排序记录序列分割为若干稀疏的子序列,分别进行插入排序。
2,时间复杂度 O(n^(3/2)),空间复杂度 O(1)。
3,稳定性:不稳定。{2,4,1,2},2和1是一组,4和2是一组,进行希尔排序后,两个2的相对位置发生了变化。
4,过程分析:
初始: 81 94 11 96 12 35 17 95 28 58 41 75 15
第一趟 d=5 35 17 11 28 12 41 75 15 96 58 81 94 95
第二趟 d=3 28 12 11 35 15 41 58 17 94 75 81 96 95
第三趟 d=1 11 12 15 17 28 35 41 58 75 81 94 95 96
5,伪码
void shellSort(vector<int> A){int N = A.size();int i, j, Incremnet;int tmp;for (Incremnet = N / 2; Incremnet > 0; Incremnet /= 2){for (int i = Incremnet; i < N; ++i){tmp = A[i];for (j = i; j >= Incremnet; j -= Incremnet){if (tmp < A[j - Incremnet])A[j] = A[j - Incremnet];elsebreak;}A[j] = tmp;}}}
三、堆排序
1,思想:将待排序的关键字存放在数组中,将这个数组看成是一棵完全二叉树的顺序表示,每个结点表示一个记录,第一个记录作为二叉树的根,以下各记录依次逐层从左到右顺序排列。
2,时间复杂度 O(nlogn),空间复杂度 O(1)。
3,稳定性:不稳定排序。{5,5,3}
4,过程分析
对于堆排序,首先建初堆,再初始化大根堆,把栈顶元素和堆尾元素交换,最后对其前面的几个元素重新进行堆调整。
http://www.cnblogs.com/chengxiao/p/6129630.html
5,伪码
#define leftChild(i) (2*(i)+1)void percDown(vector<int> A, int i,int N){int child;int tmp;for (tmp = A[i]; leftChild(i) < N; i = child){child = leftChild(i);if (child != N - 1 && A[child + 1]>A[child]) child++;if (tmp < A[child])A[i] = A[child];elsebreak;}A[i] = tmp;}void heapSort(vector<int> A, int N){int i;for (i = N / 2; i >= 0; i--)percDown(A, i,N);for (i = N - 1; i > 0; i--){swap(A[0], A[i]);percDown(A, 0,i);}}
四、归并排序
1,思想:将 n 个记录看成 n 个有序的子序列,每一个子序列的长度为 1,然后两两归并,得到 n/2 个长度为 2 的有序子序列,如此重复,直到得到一个长度为 n 的有序序列为止。
2,时间复杂度 O(nlogn) , 空间复杂度 O(n)
3,稳定性:稳定排序。
4,过程分析
初始 12 2 16 30 8 28 4 10 20 6 18
第一趟 (2 12)(16 30)(8 28)(4 10)(6 20)(18)
第二趟 (2 12 16 30)(4 8 10 28)(6 18 20)
第三趟 (2 4 8 10 12 16 28 30)(6 18 20)
第四趟 2 4 6 8 10 12 16 18 20 28 30
5,伪码
void mSort(vector<int> A, vector<int> tmp, int left, int right){int center;if (left < right){center = left + (right - left) / 2;mSort(A, tmp, left, center);mSort(A, tmp, center, right);Merge(A,tmp,left,center+1,right);}}void mergeSort(vector<int> A, int N){vector<int> tmp(N);mSort(A, tmp, 0, N - 1);}
五、快速排序
1,思想:从待排序记录中选取一个记录为枢纽元,其关键字为K,然后将其余关键字小于K的记录移到前面,而关键字大于K的记录移到后面,结果将待排序的记录序列分为两个子表,最后将关键字为K的记录插到其分界线的位置处。
Tips:枢纽元的选择:一般做法是使用左端、右端和中心位置的三个元素的中值作为枢纽元。
2,时间复杂度: 平均 O(nlogn) 最坏 O(n^2).
3,稳定性:不稳定排序。{3,1,2,2}
4,过程分析
初始 6 1 2 7 9 3 4 5 10 8
第一趟 8 1 2 7 9 3 4 5 10 6 (交换枢纽元和最后元素)
5 1 2 4 3 9 7 8 10 6
第二趟 5 1 2 4 3 6 9 7 8 10 (枢纽元两边继续排序)
2 1 5 4 3 6 8 7 10 9
5,伪码
int median3(vector<int> A, int left, int right){ // 找出三个数中值并放在最后int center = left + (right - left) / 2;if (A[left] > A[center])swap(A[left], A[center]);if (A[left] > A[right])swap(A[left], A[right]);if (A[center] > A[right])swap(A[center], A[right]);swap(A[center], A[right]);return A[right];}#define Cutoff (3)void quickSort(vector<int> A,int left,int right){int i, j;int pivot;if (left + Cutoff <= right){pivot = median3(A, left, right);i = left, j = right;while (1){while (A[++i] < pivot){}while (A[--j] > pivot){}if (i < j)swap(A[i], A[j]);elsebreak;}swap(A[i], A[right]);quickSort(A, left, i - 1);quickSort(A, i + 1, right);}elseinsertionSort(A + left, right - left + 1); // 规模小于一定大小时,用插入排序}
- 排序总结
- 排序总结
- 排序总结
- 排序总结
- 排序总结
- 排序总结
- 排序总结
- 排序总结
- 排序总结
- 排序总结
- 排序总结
- 排序总结
- 排序 -- 总结
- 排序总结
- 排序总结
- 排序总结
- 排序总结
- 排序总结
- 剑指offer----树的子结构
- python进阶学习笔记(五)——创建实例属性、初始化实例属性
- 约束高级属性Content Compression Resistance Priority和Content Hugging Priority
- 【用例】测试用例编写的一些问题
- 在windows上使用Thrift生成PHP代码
- 排序总结
- bootstrap详解-栅格布局
- 题目1037:Powerful Calculator
- 为什么InnoDB表要建议用自增列做主键而MyISAM不需要
- Tense
- 深度学习之神经网络入门(一)
- 巧用二分法实现数学开方(sqrt)运算
- Java中的二维数组
- Ubuntu 安装Arduino报错cc.arduino.arduinoide.xml does not exist解决