排序算法——堆排序

堆排序

基本思想:在排序过程中,将数据看成一棵完全二叉树,利用完全二叉树中双亲结点和子结点的关系来选择关键值最小的记录。

堆的定义:n个元素序列h1, h2, …, hn,当hi>=h2i, h2i+1时,或当hi<=h2i, h2i+1时,称为堆;前者称为大根堆,后者称为小根堆。
在这里插入图片描述
以完全二叉树表示堆,以数组r[0…n-1]存储堆。
堆调整:
若结点i的左、右子树均为堆,将r[i]与r[2i+1]和r[2i+2]比较,若不满足堆的条件,将r[2i+1]和r[2i+2]中的大者与r[i]交换;
依次向下层执行(1),直到所有子树均为堆为止。
在这里插入图片描述
建堆:对于任意一个以完全二叉树表示的堆,从i=[n/2]-1开始到0,反复调用堆调整。
堆排序
(1)建堆;
(2)交换堆的根与未排序的最后一个叶子,该叶子进入已排序序列中;
(3)对未排序二叉树进行堆调整;
(4)重复步骤(2)和(3),直至未排序二叉树为空。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
参考代码:(参考《大话数据结构》)

/* 交换L中数组r的下标为i和j的值 */
void swap(SqList *L,int i,int j) 
{ 
	int temp=L->r[i]; 
	L->r[i]=L->r[j]; 
	L->r[j]=temp; 
}
void HeapAdjust(SqList *L,int s,int m)
{ 
	int temp,j;
	temp=L->r[s];
	for(j=2*s;j<=m;j*=2) /* 沿关键字较大的孩子结点向下筛选 */
	{
		if(j<m && L->r[j]<L->r[j+1])
			++j; /* j为关键字中较大的记录的下标 */
		if(temp>=L->r[j])
			break; /* rc应插入在位置s上 */
		L->r[s]=L->r[j];
		s=j;
	}
	L->r[s]=temp; /* 插入 */
}

/*  对顺序表L进行堆排序 */
void HeapSort(SqList *L)
{
	int i;
	for(i=L->length/2;i>0;i--) /*  把L中的r构建成一个大根堆 */
		 HeapAdjust(L,i,L->length);

	for(i=L->length;i>1;i--)
	{ 
		 swap(L,1,i); /* 将堆顶记录和当前未经排序子序列的最后一个记录交换 */
		 HeapAdjust(L,1,i-1); /*  将L->r[1..i-1]重新调整为大根堆 */
	}
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值