您的位置:首页 > 其它

堆排序

2010-04-10 12:20 120 查看
堆排序,建立在堆这种结构上。一般的堆可以建立在数组上,但也可以用链表结构来表示。有序堆满足,每个节点的键值要比它所有孩子的键值都大。

#include <iostream>
using namespace std;
typedef double Elem;
/* 自顶向下堆化(大根堆)
fixDown(Elem* eArray, int k, int N)
问题功能描述:
假设原来的堆是有序的,只是位置k上的键值下降了,将位置k上的元素放到一个适当的位置上,使其满足堆的条件。
procedure (eArray, k , N)
while (2 * k <= N) // 存在孩子节点,"="的时候只有一个孩子节点
{
找到键值较大的孩子节点的位置j(注意只有一个孩子节点的情况)
if eArray[k] < eArray[j]
{
交换位置k和位置j上的元素;
将k设置为j; //因为交换位置k和位置j上的元素之后,以位置j上的元素为根的堆变得无序了,所以继续堆化
}
else
{
当前位置k就是eArray[k]的最终位置;
跳出循环;
}
}
*/

inline bool Less(Elem& e1, Elem& e2) {return e1 < e2;}
inline void Exch(Elem& e1, Elem& e2) { Elem e = e1; e1 = e2; e2 = e;}

void FixDown(Elem* eArray, int k, int N)
{
int j = 2 * k; // 键值最大的孩子节点的位置
while (j <= N)
{
// 找到键值最大的孩子节点
if (j < N && Less(eArray[j], eArray[j+1]))
{
j++;
}

if (!Less(eArray[k], eArray[j]))
{
break;
}

Exch(eArray[k], eArray[j]);
k = j;
j = 2 * k;
}
}

/* 堆排序
1、自底向上,自左向右构建堆
2、将第一个元素(键值最大)与最后一个元素交换,堆的元素数目减1,调整堆。
3、循环执行第2步,直到堆为空。
*/

/*eArray 为元素数组(下标从1开始),totalNum为元数目*/
void HeapSort(Elem* eArray, int totalNum)
{
int const N = totalNum;
// 构建堆
int k;
for (k = totalNum / 2; k >= 1; k--)
{
FixDown(eArray, k, totalNum);
}

while (totalNum > 1)
{
Exch(eArray[1], eArray[totalNum]);
FixDown(eArray, 1, --totalNum);
}
}

int main()
{
Elem a[10] = {0, 1, 2, 9, 4, 8, 6, 7, 5, 3};
int totalNum = 9;

cout << "未排序前的序列:" << endl;
int i;
for (i = 1; i < totalNum; i++)
{
cout << a[i] << ", ";
}
cout << a[totalNum] << endl;
HeapSort(a, totalNum);
cout << "排序之后的序列:" << endl;

for (i = 1; i < totalNum; i++)
{
cout << a[i] << ", ";
}
cout << a[totalNum] << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: