数据结构之选择排序之堆排序(参考严蔚敏数据结构)

本文详细介绍了堆这种数据结构,包括大顶堆的概念,并提供了堆调整和创建大顶堆的算法。通过堆排序函数的实现,展示了如何使用堆排序对顺序表进行升序排列。最后,给出了一个简单的堆排序示例程序,用于演示排序过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//堆是一种存储结构,是满足完全二叉树的顺序存储结构
//理解大顶堆
//堆调整函数是对以当前结点为根结点的堆进行调整使其成为大顶堆,且默认只有根结点可能不满足大顶堆,根结点的所有子孙结点(如果有)皆满足大顶堆
//创建大顶堆函数是对所有的结点构成的堆经过从i=[n/2]直至i=1反复调用堆调整函数实现的
//堆排序函数是创建大顶堆之后,重复进行如下操作最终完成堆排序:将堆顶元素和最末尾的元素互换,更新后的末尾元素到位(最终排序成功后的位置)并不在堆调整范围内,
    //调用堆调整函数(因为只有堆顶元素可能不满足最大堆性质)

#include<iostream>
using namespace std;

#define MAXSIZE 20 // 一个用作示例的小顺序表的最大长度
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
typedef int InfoType; // 定义其它数据项的类型
typedef int KeyType; // 定义关键字类型为整型
typedef struct RedType // 记录类型
{
	KeyType key; // 关键字项
	InfoType otherinfo; // 其它数据项,具体类型在主程中定义
}RedType;
typedef struct SqList // 顺序表类型
{
	RedType r[MAXSIZE + 1]; // r[0]闲置或用作哨兵单元
	int length; // 顺序表长度
}SqList;
typedef SqList HeapType; // 堆采用顺序表存储表示

void HeapAdjust(HeapType &H, int s, int m)//局部调整
{ // 已知H.r[s..m]中记录的关键字除H.r[s].key之外均满足堆的定义,本函数
	// 调整H.r[s]的关键字,使H.r[s..m]成为一个大顶堆(对其中记录的关键字而言)
	RedType rc;
	int j;
	rc = H.r[s];
	for (j = 2 * s; j <= m; j *= 2)
	{ // 沿key较大的孩子结点向下筛选
		if (j<m&<(H.r[j].key, H.r[j + 1].key))//如果j下标对应key有右兄弟且key小于右兄弟key
			++j; // 更新j,j为key较大的记录的下标
		if (!LT(rc.key, H.r[j].key))
			break; // rc应插入在位置s上
		else
		{
			H.r[s] = H.r[j];
			s = j;
		}
	}
	H.r[s] = rc; // 插入
}

void CreateMTHeap(HeapType &H)//全局调整
{// 把H.r[1..H.length]建成大顶堆
	int i;
	for (i = H.length / 2; i > 0; --i)
		HeapAdjust(H, i, H.length);//调用堆调整函数使i下标对应的结点为根结点的堆成大顶堆
}

void HeapSort(HeapType &H)
{ // 对顺序表H进行堆排序
	RedType t;
	int i;
	CreateMTHeap(H);
	for (i = H.length; i>1; --i)
	{  /*将堆顶记录和当前未经排序子序列H.r[1..i]中最后一个记录相互交换,之后i下标对应元素到位(排序后应该在的位置)*/
		t = H.r[1];
		H.r[1] = H.r[i];
		H.r[i] = t;
		/*****************************************************************************************************8*/
		HeapAdjust(H, 1, i - 1); // 将H.r[1..i-1]重新调整为大顶堆
	}
}

void print(HeapType H)
{
	int i;
	for (i = 1; i <= H.length; i++)
		printf("(%d,%d)", H.r[i].key, H.r[i].otherinfo);
	printf("\n");
}

#define N 8
void main()
{
	RedType d[N] = { { 49, 1 }, { 38, 2 }, { 65, 3 }, { 97, 4 }, { 76, 5 }, { 13, 6 }, { 27, 7 }, { 49, 8 } };
	HeapType h;
	int i;
	for (i = 0; i<N; i++)
		h.r[i + 1] = d[i];
	h.length = N;
	printf("排序前:\n");
	print(h);
	HeapSort(h);
	printf("排序后:\n");
	print(h);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值