标签:排序算法
希尔排序
又称缩小增量排序
先给数组设定一个增量,一般数组长度为len,同常将增量设为increment = len/2,increment每次缩小为原来的1/2。
1、通过这个增量给数组里的数分组:例如 0,0+increment, 0+2*increment,... 为一组 1,1+increment, 1+2*increment,...为另外一组。
2、对于每一个组通过插入算法进行排序。(前面已经写了折半插入排序,这里写的是普通插入排序)
3、increment = increment/2,然后继续循环
代码:shell_sort.cc
#include<iostream> #include<vector> using namespace std; template< class T > void shell_sort(vector<T> &a){ int len = a.size(); int i,j; T tmp; int increment; for ( increment = len/2; increment >0; increment /= 2){ for ( i = increment; i < len; i++){ tmp = a[i]; for ( j = i; j >=increment; j -= increment){ if ( tmp < a[j - increment] ) a[j] = a[ j - increment]; else{ break; } } a[j] = tmp; } } } int main(int argc, char **argv){ vector<int> a = {10, 8, 9, 1, 7, 4, 11, 23, 3, 2, 5}; vector<int>::iterator iter; shell_sort<int>( a ); for( iter = a.begin(); iter != a.end(); iter++){ cout<< *iter <<" "; } cout << endl; return 0; }运行结果:
jdh@jdh-virtual-machine:~/program/datastruct/c_plus/sort$ ./a.out
1 2 3 4 5 7 8 9 10 11 23
快速排序
#include<iostream> #include<vector> using namespace std; template<class T> int partition(vector<T> &a, int left, int right){ int i = left; int j = right; T key = a[right]; for( j = left; j < right; j++){ if ( a[j] < key ){ swap(a[j], a[i]); ++i; } } swap(a[i] , a[right]); return i; } template<class T> void quick_sort(vector<T> &a, int left, int right){ if ( left < right){ int q = partition(a, left, right); quick_sort(a, left, q-1); quick_sort(a, q+1, right); } } int main(int argc, char **argv){ vector<int> a = {10, 8, 9, 1, 7, 4, 11, 23, 3, 2, 5}; int len = a.size(); vector<int>::iterator iter; quick_sort<int>(a, 0, len-1); for( iter = a.begin(); iter != a.end(); iter++){ cout<< *iter <<" "; } cout << endl; return 0; }运行结果:
jdh@jdh-virtual-machine:~/program/datastruct/c_plus/sort$ g++ -std=c++11 quik_sort.cc
jdh@jdh-virtual-machine:~/program/datastruct/c_plus/sort$ ./a.out
1 2 3 4 5 7 8 9 10 11 23
堆排序
性质:
1、二叉堆在逻辑上是一个完全二叉树,但是我们可以采用数组的方式存储。
如果二叉堆数组从1开始存储,那么父亲i的左孩子下标为2i,右孩子下标为2i+1;同理结点i的父亲下标为i/2。
如果二叉堆数组从0开始,则父结点i左孩子的下标为2i+1,右孩子的下标2i+2.
2、小根堆,一个结点的权值小于其所在在子树其它结点的权值。
大根堆,一个结点的权值大于其所在子树其它结点的权值。
堆排序步骤;
1、将普通数组转换成大根堆数组
2、 a.将大根堆的第一个数和数组的最后一个数交换,修正除了最后一个数以外其余数的大根堆性质
b.重复a的步骤
#include<iostream> #include<vector> using namespace std; inline int left(int i){ return 2*i+1; } inline int right(int i){ return 2*i+2; } template<class T> void build_child_max_heap(vector<T> &a, int i, int len){ int max = i; if ( left(i) < len ){ if ( a[i] < a[left(i)]) max = left(i); } if ( right(i) < len){ if ( a[right(i)] > a[max] ) max = right(i); } if ( max != i){ swap(a[max], a[i]); build_child_max_heap(a, max, len); } } template<class T> void build_max_heap(vector<T> &a){ int len = a.size(); for ( int i = (len-1)/2; i >= 0; --i) build_child_max_heap(a, i, len); } template<class T> void heap_sort(vector<T> &a, int len){ build_max_heap(a); for ( int i = len - 1; i > 0; --i){ swap(a[0], a[i]); build_child_max_heap(a, 0, i); } } int main(int argc, char **argv){ vector<int> a = {6, 8, 9, 1, 7, 4, 11, 23, 3, 2, 5}; int len = a.size(); vector<int>::iterator iter; heap_sort(a, len); for( iter = a.begin(); iter != a.end(); iter++){ cout<< *iter <<" "; } cout << endl; return 0; }
jdh@jdh-virtual-machine:~/program/datastruct/c_plus/sort$ g++ -g -std=c++11 heap_sort.cc
jdh@jdh-virtual-machine:~/program/datastruct/c_plus/sort$ ./a.out
1 2 3 4 5 6 7 8 9 11 23
版权声明:本文为博主原创文章,未经博主允许不得转载。
自己动手实现数据结构——排序算法2 (希尔、快速、堆)(C++实现)
标签:排序算法
原文地址:http://blog.csdn.net/sshhiixx/article/details/47689683