堆排序的研究与分析

      在此排序过程中,我并没有建立一个真正的二叉堆,而是用一个数组来模拟堆,每次把通过回溯找到的最大或最小元素与最后一个元素交换,最后形成一个顺序的数组。

      首先我们来看一下小元素下移与大孩子上移的算法,与二叉堆的建立基本相同。

#define leftchild(i) (2*i+1)
void PerDown(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];
		else
			break;
	}
	a[i]=tmp;
}
      i代表当前的位置,我们还定义了计算左孩子的直接过程,第一个if找出了i节点的大孩子,第二个if把让大孩子上移,保证了该节点比两个孩子都大,最后是该节点应该放置 的位置。

      接下来我们来看一下建堆的过程,代码上来:

void HeapSort(int a[],int n)//堆排序实现的函数
{
	int i;
	for(i=n/2;i>=0;i--)//从中间往上建立一个堆,会检查孩子的大小
	{
		PerDown(a,i,n);
	}
	for(i=n-1;i>0;i--)
	{
		swap(a[0],a[i]);//交换首位的位置,交换之后最后一个元素是最大的
		PerDown(a,0,i);//只给前n个数下移
	}
}

      从所有节点的一半位置处往上建立就可以了,因为叶子节点没有孩子。每次建完都交换首尾的位置,然后再下移即可,最后形成一个完整的有序数组。

      总结:堆排序是一个非常稳定的算法,对于n个互异的随机排列的数组,所用的平均比较次数为2nlogn-O(nloglogn),约为2nlogn-O(n)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值