堆排序

堆可分为最大堆和最小堆。

最大堆:根节点的值大于左右结点的值。表达式:  digit[i] > digit[2*i+1]  && digit[i] > digit[2*i+2]
最小堆:根节点的值小于左右结点的值。表达式:  digit[i] < digit[2*i+1] && digit[i] <  digit[2*i+2]

例如:最大堆

堆排序的实现:例子很简单

/*
 * 堆排序基本思想:
 *    把待排的数据元素集合构成一个“完全二叉树”
 *那么每次选择出一个最大(最小)的数据元素秩序比较
 *完全二叉树的深度(lbn),那么排序算法的时间复杂度
 *就是O(nlbn).
 *算法步骤:
 *(一):将一个线性数组结构初始化成完全二叉树的逻辑结构。(创建堆)
 * 关键点:
 *      初始化创建堆得过程就是从第一个“非叶”节点开始,到根节点
 *   为止。
*/
// 堆排序的实现:
#include <iostream>
#include <iomanip>
using namespace std;

#define Size 20
typedef int DataType;

void InitiateCrateHeap(DataType digit[], int lengthOfDigit);//这里的数组长度,可以理解成完全二叉树节点的个数
void CreateHeap(DataType digit[], int lengthOfDigit, int root);
void PaintHeapSort(DataType digit[], int lengthOfDigit);
void HeapSort(DataType digit[], int lengthOfDigit);

int main(void)
{
	DataType digit[Size] ={ 
	   12, 15, 34, 25, 45,
	   78, 68, 39, 29, 28,
	   98, 43, 54, 83, 93,
	   18, 39, 27, 42, 78};
	PaintHeapSort(digit, Size);
	HeapSort(digit, Size);
	PaintHeapSort(digit, Size);
	return 0;
}

/初始化创建“最大堆”
void InitiateCrateHeap(DataType digit[], int lengthOfDigit)//这里的数组长度,可以理解成完全二叉树节点的个数
{
	cout<<"After Create..."<<endl;
	int i =  0;
	for(i = (lengthOfDigit-2)/2; i >=0; i--) // 这就是从第一个“非叶节点”
		CreateHeap(digit, lengthOfDigit,i);//调用
}
void CreateHeap(DataType digit[], int lengthOfDigit, int root)
{
	DataType temp;
	int   flag = 0; // 标记
	int   i;
	int   j;
	i = root; // i 是要建堆的二叉树根节点下标
	j = 2*i+1; // j 是要建堆的二叉树根节点左孩子的下标

	while( j < lengthOfDigit && flag != 1)
	{
		if(j < lengthOfDigit-1 && digit[j] < digit[j+1]) j++; //判断根节点的左右节点的最大值,并记录下最大值的下标
		if(digit[i] > digit[j]) flag = 1; // 根节点的值 > 左右节点的值,退出循环
		else//将左右结点中的最大的那个节点 与 根节点互换
		{
			temp = digit[i];
			digit[i] = digit[j];
			digit[j] = temp;
			i = j;//下一个根节点
			j = 2*i+1;//下一个根节点的左节点
		}
	}

}
//以上两步是CreateHeap(创建堆),接下来是堆排序HeapSort
void HeapSort(DataType digit[], int lengthOfDigit)
{
	int i;
	DataType temp;

	//堆排序前先初始化堆
	InitiateCrateHeap(digit, lengthOfDigit);

	for(i = lengthOfDigit-1; i > 0; i--) //排序思想:
	{                                    // (1)把堆顶的元素digit[0]和最大堆的最后一个元素交换
		temp = digit[i];             // (2)最大堆的个数减一
		digit[i] = digit[0];         // (3)由于(1)后根节点不满足最大堆的定义,需要调整最大堆
		digit[0] = temp;

		CreateHeap(digit, i, 0); // 此时堆中的元素个数是 i 个

	}
}
/输出
void PaintHeapSort(DataType digit[], int lengthOfDigit)
{
	for(int i = 0; i <lengthOfDigit; i++)
		cout<<digit[i]<<setw(4);
	cout<<endl;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值