1、堆排序
堆排序 的基本思想:充分利用了完全二叉树的深度为 log2N + 1。首先将待排序序列构造成一个大(小)顶堆。此时,堆顶的根结点就是整个序列的最大值,将根结点与最后一个结点交换(移走根节点)。然后调整,将剩余的N-1个记录重新构造成一个大(小)顶堆,此时,堆顶的根结点就是整个序列的最大值。。。。。反复执行,直到得到一个有序序列。
转(http://www.cnblogs.com/mengdd/archive/2012/11/30/2796845.html)
参考(http://blog.csdn.net/morewindows/article/details/6709644/)
参考(http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html)
堆的定义:
例如,下列两个序列为堆,对应的完全二叉树如图: (若将和此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。)
若在输出堆顶的最小值之后,使得剩余n-1个元素的序列重又建成一个堆,则得到n个元素的次小值。如此反复执行,便能得到一个有序序列,这个过程称之为堆排序。
堆排序(Heap Sort)只需要一个记录元素大小的辅助空间(供交换用),每个待排序的记录仅占有一个存储空间。
堆的存储:
一般用数组来表示堆,若根结点存在序号0处, i结点的父结点下标就为(i-1)/2。i结点的左右子结点下标分别为2*i+1和2*i+2。(注:如果根结点是从1开始,则左右孩子结点分别是2i和2i+1。)
如最大化堆如下:
左图为其存储结构,右图为其逻辑结构。
2、堆排序实例
首先,建立初始的堆结构如图:
然后,交换堆顶的元素和最后一个元素,此时最后一个位置作为有序区(有序区显示为黄色),然后进行其他无序区的堆调整,重新得到大顶堆后,交换堆顶和倒数第二个元素的位置……
重复此过程:
最后,有序区扩展完成即排序完成:
由排序过程可见,若想得到升序,则建立大顶堆,若想得到降序,则建立小顶堆。
3、堆排序的实现
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<algorithm>
using namespace std;
//******每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换******//
void HeapAdjust(int *a, int i, int size) //调整堆
{
int lchild = 2 * i; //i的左孩子节点序号
int rchild = 2 * i + 1; //i的右孩子节点序号
int max = i; //临时变量
if (i <= size / 2) //如果i是叶节点就不用进行调整
{
if (lchild <= size&&a[lchild]>a[max])
{
max = lchild;
}
if (rchild <= size&&a[rchild]>a[max])
{
max = rchild;
}
if (max != i)
{
swap(a[i], a[max]);
HeapAdjust(a, max, size); //避免调整之后以max为父节点的子树不是堆
}
}
}
void BuildHeap(int *a, int size) //建立堆
{
int i;
//**************建堆的时候:是从底部开始往上层上溯**************//
for (i = size / 2; i >= 1; i--) //非叶节点最大序号值为size/2
{
HeapAdjust(a, i, size);
}
}
void HeapSort(int *a, int size) //堆排序
{
int i;
BuildHeap(a, size); //建堆
for (i = size; i >= 1; i--)
{
swap(a[1], a[i]); //交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面
//BuildHeap(a,i-1); //将余下元素重新建立为大顶堆
//**************拆堆的时候:是从顶部开始往下层下溯**************//
HeapAdjust(a, 1, i - 1); //重新调整堆顶节点成为大顶堆
}
}
int main(int argc, char *argv[])
{
//int a[]={0,16,20,3,11,17,8};
int a[100];
int size;
while (scanf("%d", &size) == 1 && size>0)
{
int i;
for (i = 1; i <= size; i++)
cin >> a[i];
HeapSort(a, size);
for (i = 1; i <= size; i++)
cout << a[i] << " ";
cout << endl;
}
return 0;
}
4、总结: