堆排序

堆排序是一种利用二叉树性质进行排序的方法,它将待排序序列构造成一个大顶堆或小顶堆,然后将堆顶元素与末尾元素交换并移除,重复该过程直到整个序列有序。这种方法在处理大量数据时效率较高,但对小规模数据排序并不理想。
摘要由CSDN通过智能技术生成

        堆排序其实就是借助于数据结构中二叉树的思想来进行排序,将需要排序的数据看成一个从上往下,从左到右排列的完全二叉树。从最后带有子节点的节点开始进行筛选,将最大或最小的数据移到根节点的位置,将这个根节点拿出来,重新在剩下的数据中寻找另一个根节点。

        堆排序在比较使具有记忆功能,所以可以减少数据的比较次数。对数据量比较的排序比较有效,但对于数据比较小的排序不提倡。

/************************************************************************/
/* Function:堆排序                                                      */
/* Parameter:array[]将要被排序的数组,len:array数组的长度             */
/* return:void                                                         */
/************************************************************************/
void HeapSort(int array[], int len)
{
	for (int i = len/2 - 1; i >= 0; --i)
	{
		HeapAdjust(array, i, len);   //从最后一个有孩子节点的元素开始排序,这个节点的下表即为len/2 - 1
	}
	for (int j = len - 1; j > 0; --j)
	{
		int temp = array[0];  //此时根节点为筛选数据中的最大值,或最小值,把这个值取出来,与数组最后位置上需要筛选的节点进行交换
		array[0] = array[j];
		array[j] = temp;
		HeapAdjust(array, 0, j);  //原来根节点以下的节点都经过筛选,所以只需根节点筛选
	}
	return;
}

/************************************************************************/
/* Function:节点筛选与移动,将数据较小的节点往根节点移动                */
/* Parmeter:array[]:将要被排序的数组,s:筛选节点在数组中的位置,m:筛选 */
/*                    的数组的长度                                      */
/* Return: void                                                         */
/************************************************************************/
void HeapAdjust(int array[], int s, int m)
{
	int temp = array[s];  //标记筛选节点的值
	for (int j = 2 * s + 1; j  < m; j = 2 * j + 1)  //循环将筛选节点与子节点,孙节点比较
	{
		if ((j < m - 1) && (array[j] > array[j + 1]))  //判断节点的两个子节点的大小,找出根节点中数据较小的节点为比较节点
		{
			j++;
		}
		if (temp <= array[j])  //若筛选节点比较小的子节点的数据还小,则退出循环,不需要与子节点交换位置
		{
			break;
		}
		array[s] = array[j];  //若当前节点比较小的子节点的数据要大,则将数据较小的子节点往上移
		s = j;   //空出来的位置,暂时想象用来存放筛选节点,将来或许存放比当前筛选节点更小的孙节点
	}
	array[s] = temp;  //最后空出来的位置存放筛选节点
	return;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值