您的位置:首页 > 理论基础 > 数据结构算法

数据结构 - 堆排序

2013-06-13 16:07 218 查看
 堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

堆排序定义
     n个关键字序列Kl,K2,…,Kn称为堆,当且仅当该序列满足如下性质(简称为堆性质):
     (1) ki≤K2i且ki≤K2i+1 或(2)Ki≥K2i且ki≥K2i+1(1≤i≤ 

 )
     若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。

    下图来自《算法导论》中堆排序一节:放到这里帮助大家更形象的理解堆。



图(a)是一个最大堆,图(b)是最大堆的数组表示。

#include <stdio.h>

void HeapAdjust(int A[], int start, int len)
{
//i为要调整的节点
int i = start;
//c中保存i节点的左孩子
int c = i * 2 + 1; //+1的目的是为了解决节点从0开始而他的左孩子一直为0的问题

while (c < len)//未调整到叶子节点
{
//如果要调整的节点既有左孩子又有右孩子并且左孩子值小于右孩子
//从二者中选出较大的并记录
if (c + 1 < len && A[c] < A[c + 1])
c++;
//如果要调整的节点中的值大于左右孩子的较大者则退出
if (A[i] > A[c]) break;
else
{
//交换
int t = A[c];
A[c] = A[i];
A[i] = t;
//重置要调整的节点和要调整的左孩子
i = c;
c = 2 * i + 1;
}
}
return;
}

void HeapSort(int A[], int n)
{
//初始化建堆, i从最后一个非叶子节点开始
for (int i = (n - 2) / 2; i >= 0; i--)
HeapAdjust(A, i, n);

for (int j = 0; j < n; j++)
{
//交换
int t = A[0];
A[0] = A[n - j - 1];
A[n - j - 1] = t;

//调整编号为0
HeapAdjust(A, 0, n - j - 1);
}
}

int main()
{
int a[] = {31, 41, 59, 26, 53, 58, 97};
HeapSort(a, sizeof(a) / sizeof(*a));

for(int i = 0; i < sizeof(a) / sizeof(*a); i++)
printf("%d\t", a[i]);
printf("\n");

return 0;
}函数:HeapAdjust为一次调整的过程,(全部调整过程需要从后向前从第一个非叶节点开始,直到根节点依次调整,即做一次HeapAdjust函数调整)。
函数:HeapSort先对数据建堆,即将其全部调整为正确的堆结构(如:大顶堆),然后依次从后向前,将最后一个堆中元素与堆顶元素互换,可得到堆顶的最大元素,接着调整除该最大元素以外的堆。直到最后。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: