堆排序
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;
}
#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;
}
相关文章推荐
- 数据结构实验之排序四:寻找大富翁——堆排序
- 归并排序、快速排序、堆排序
- 【排序二】选择排序(选择排序&&堆排序)
- 插入排序和堆排序
- 堆排序
- 算法-java代码实现堆排序
- java实现:快速排序,基数排序,计数排序,归并排序,堆排序,希尔排序
- 排序算法2--简单选择排序、堆排序
- 排序算法(二)选择类排序:简单选择排序,堆排序,锦标赛排序
- 常见排序算法总结与实现(冒泡、插入、选择、希尔、堆排序、归并、快排)
- 排序算法2--简单选择排序、堆排序
- 堆排序
- 排序算法-堆排序
- PERL算法-加入子程序的堆排序
- 经典的排序算法--堆排序
- 常用排序算法(冒泡、插入、选择、快速排序、堆排序)
- 算法基础 大根堆与堆排序
- 【每日算法】选择排序算法之堆排序
- Java实现堆排序
- 排序算法之堆排序(JAVA实现)