您的位置:首页 > 其它

堆排序与直接选择排序的比较

2010-07-15 21:35 302 查看
直接选择排序基本思想是:第一次从R[0]~R[n-1]中选取最小值,与R[0]交换,第i次从R[i-1]~R[n-1]中选取最小值,与R[i-1]交换,.....,第n-1次从R[n-2]~R[n-1]中选取最小值,与R[n-2]交换,总共通过n-1次,得到一个按排序码从小到大排列的有序序列.

直接选择排序中,为了从R[1..n]中选出关键字最小的记录,必须进行n-1次比较,然后在R[2..n]中选出关键字最小的记录,又需要做n-2次比较。事实上,后面的n-2次比较中,有许多比较可能在前面的n-1次比较中已经做过,但由于前一趟排序时未保留这些比较结果,所以后一趟排序时又重复执行了这些比较操作,时间复杂度为log(n2)。

堆排序可通过树形结构保存部分比较结果,可减少比较次数,时间复杂度为nlogn。

直接选择排序

#include<iostream>
using namespace std;
typedef int ElemType ;
//该代码数组下标从0开始,从1开始的话要修改
void HeapAdjust(ElemType array[],int begin,int end)
{/*array[begin...end]中,除array[begin]外,其他满足大根堆,
调整array[begin]使array[begin...end]成为一个大根堆
*/
ElemType tempData;//暂存元素
tempData = array[begin];
for(int i=2*begin+1; i<=end; i=2*i+1)
{/*每次调整,只有根可能不满足大根堆条件,将其与其孩子树的
根比较,向下筛选*/
if(i<end && array[i] < array[i+1])//注意i<end是正确的
i++;//找出要调整的根节点有较大根节点的孩子树
if(tempData >= array[i])
break;//已是大根堆,不用调整
/*否则,进行下面的交换,注意该交换不想其他排序的交换*/
array[begin] = array[i];
begin = i;
/*用begin记录待插入元素的下标,以便下次array[begin] = array[i];
或array[begin] = tempData;能正确插入*/
}
array[begin] = tempData;//将备份元素插入begin的所指
}
void HeapSort(ElemType a[],int n)
{
int j;
ElemType temp;
/*对还不是堆的元素[0...(n/2-1)]进行堆初始化*/
for( j=n/2-1; j>=0; j--)
{
HeapAdjust(a,j,n-1);
}
for(j=n-1; j>0; j--)
{
/*将大根堆的根调到最后一个*/
temp = a[0];
a[0] = a[j];
a[j] = temp;
/*待排元素减一,对a[0...j-1]进行堆调整*/
HeapAdjust(a,0,j-1);
}
}
int main()
{
ElemType ff[10] = {3,1,6,4,5,2,8,7,9,0};
HeapSort(ff,10);
for(int k=0; k<sizeof(ff)/sizeof(ElemType); k++)
{
cout<<ff[k]<<" ";
}
cout<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  n2