排序算法汇总三------选择类排序法
2017-02-01 23:02
176 查看
选择排序有简单选择排序、树形选择排序、堆排序,其中简单排序的思想是每次从剩下的数据中选出最大的或者是最小的数据,存放在特定位置,再重复该项操作,复杂度为0(n*n),这种思想太多简单,这里就不进行诉说,树形选择排序的思想是先把待排序的n个记录的关键字两两比较,取出较小者,然后又从抽取出的较小者中两两比较取出较小者,如此反复,最后会形成一棵树,若不满足2的倍数可以用正无穷来代替,该算法通过将比较值记录下来,可以得到o(nlog(n))的复杂度,但若是数据较多时,该算法会占据较大的空间,从而产生不足,堆排序是该类算法中的较好者,也是树形选择排序的扩展,接下来也主要讲讲堆排序。
堆排序思想:
首先要区分大根堆和小根堆,大根堆是指父节点的值要大于左、右子节点,小根堆就是指父节点的值要小于左、右子节点,采用堆排序只要一个记录大小的辅助空间,其他都是数据的正常空间。首先将数据集看成一个二叉树,根节点为i时,左子节点为2*i,右子节点为2*i+1,如此类推,以大根堆为例,每次寻找时,找出左右子树点的最大值,来赋值给根节点,保证根节点最大,建初堆时,这里采用自底向上的思想,首先从最后一个非叶节点开始(n/2),保证该节点为最大(比左右子节点大),再依次往上寻找,至于为什么n/2为最后一个非叶节点,读者可以查看二叉树的概念。其他看以下代码注释:
堆排序(大根堆):
总的测试代码:
堆排序思想:
首先要区分大根堆和小根堆,大根堆是指父节点的值要大于左、右子节点,小根堆就是指父节点的值要小于左、右子节点,采用堆排序只要一个记录大小的辅助空间,其他都是数据的正常空间。首先将数据集看成一个二叉树,根节点为i时,左子节点为2*i,右子节点为2*i+1,如此类推,以大根堆为例,每次寻找时,找出左右子树点的最大值,来赋值给根节点,保证根节点最大,建初堆时,这里采用自底向上的思想,首先从最后一个非叶节点开始(n/2),保证该节点为最大(比左右子节点大),再依次往上寻找,至于为什么n/2为最后一个非叶节点,读者可以查看二叉树的概念。其他看以下代码注释:
堆排序(大根堆):
void sift(int *d,int r,int length) //d是数据源 r为当前要调整的数据下标 length为长度 { int now=d[r]; //保存数据 int i=r,j=2*i; //j为i的左子 bool finish=false; //用于标记是否完成 while(j<=length && !finish) { //若j未达到最大的右子 并且右子比左子大 则用右子来进行下轮比较 if(j<length && d[j]<d[j+1]) {j=j+1;} //比较当前要比较的值是否比子孙中大的值大,若大则正确 if(now >= d[j]) { finish=true; } //若小则用大值赋值给i下标位 //用j来赋值i,接下来继续寻找 else { d[i]=d[j]; i=j; j=2*i; } } d[i]=now; } void crt_heap(int *d,int length) { int n=length; //n/2是树中最后一个非叶子点,该点是有孩子的,之后的点都无孩子 //从后开始往前,把下面进行排序,自底向上 for(int i=n/2;i>=1;i--) { sift(d,i,n); } } void HeapSort(int *d,int length) //排序数列为1...length { crt_heap(d,length); for(int i=length;i>=2;i--) { int b=d[1]; d[1]=d[i]; d[i]=b; sift(d,1,i-1); } }
总的测试代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> using namespace std; int data[11]={0,1,2,5,6,3,8,1,9,10,12}; void Print(int *d,int length) { for(int i=0;i<length;i++) { printf("%d ",d[i]); } printf("\n\n\n"); } void sift(int *d,int r,int length) { int now=d[r]; int i=r,j=2*i; bool finish=false; while(j<=length && !finish) { if(j<length && d[j]<d[j+1]) {j=j+1;} if(now >= d[j]) { finish=true; } else { d[i]=d[j]; i=j; j=2*i; } } d[i]=now; } void crt_heap(int *d,int length) { int n=length; for(int i=n/2;i>=1;i--) { sift(d,i,n); } } void HeapSort(int *d,int length) //排序数列为1...length { crt_heap(d,length); for(int i=length;i>=2;i--) { int b=d[1]; d[1]=d[i]; d[i]=b; sift(d,1,i-1); } } int main() { HeapSort(data,10); Print(data+1,10); return 0; }