堆可分为最大堆和最小堆。
最大堆:根节点的值大于左右结点的值。表达式: 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;
}