无聊时总结总结算法之07堆排序

来源:互联网 发布:国家数据标准规范 编辑:程序博客网 时间:2024/05/16 17:01

堆排序

  1. 二叉堆的定义

二叉堆是完全二叉树或者是近似完全二叉树。

二叉堆满足二个特性:

1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。

2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。

当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆。下图展示一个最小堆:
这里写图片描述
由于其它几种堆(二项式堆,斐波纳契堆等)用的较少,一般将二叉堆就简称为堆

实现堆排序

实现堆排序需解决两个问题:
1. 如何将n 个待排序的数建成堆;
2. 输出堆顶元素后,怎样调整剩余n-1 个元素,使其成为一个新堆。

首先讨论第二个问题:输出堆顶元素后,对剩余n-1元素重新建成堆的调整过程。
调整小顶堆的方法:
1)设有m 个元素的堆,输出堆顶元素后,剩下m-1 个元素。将堆底元素送入堆顶((最后一个元素与堆顶进行交换),堆被破坏,其原因仅是根结点不满足堆的性质。
2)将根结点与左、右子树中较小元素的进行交换。
3)若与左子树交换:如果左子树堆被破坏,即左子树的根结点不满足堆的性质,则重复方法 (2).
4)若与右子树交换,如果右子树堆被破坏,即右子树的根结点不满足堆的性质。则重复方法 (2).
5)继续对不满足堆性质的子树进行上述交换操作,直到叶子结点,堆被建成。

再讨论对n 个元素初始建堆的过程
建堆方法:对初始序列建堆的过程,就是一个反复进行筛选的过程。
1)n 个结点的完全二叉树,则最后一个结点是第个结点的子树。
2)筛选从第个结点为根的子树开始,该子树成为堆。
3)之后向前依次对各结点为根的子树进行筛选,使之成为堆,直到根结点。

/** * 已知H[s…m]除了H[s] 外均满足堆的定义 * 调整H[s],使其成为大顶堆.即将对第s个结点为根的子树筛选, * * @param H是待调整的堆数组 * @param s是待调整的数组元素的位置 * @param length是数组的长度 * */void HeapAdjust(int H[],int s, int length){    int tmp  = H[s];    int child = 2*s+1; //左孩子结点的位置。(i+1 为当前调整结点的右孩子结点的位置)    while (child < length) {        if(child+1 <length && H[child]<H[child+1])        { // 如果右孩子大于左孩子(找到比当前待调整结点大的孩子结点)            ++child ;        }        if(H[s]<H[child])        {  // 如果较大的子结点大于父结点            H[s] = H[child]; // 那么把较大的子结点往上移动,替换它的父结点            s = child;       // 重新设置s ,即待调整的下一个结点的位置            child = 2*s+1;        }        else // 如果当前待调整结点大于它的左右孩子,则不需要调整,直接退出        {             break;        }        H[s] = tmp; // 当前待调整的结点放到比其大的孩子结点位置上    }    print(H,length);}/** * 初始堆进行调整 * 将H[0..length-1]建成堆 * 调整完之后第一个元素是序列的最小的元素 */void BuildingHeap(int H[], int length){    //最后一个有孩子的节点的位置 i=  (length -1) / 2    for (int i = (length -1) / 2 ; i >= 0; --i)        HeapAdjust(H,i,length);}/** * 堆排序算法 */void HeapSort(int H[],int length){    //初始堆    BuildingHeap(H, length);    //从最后一个元素开始对序列进行调整    for (int i = length - 1; i > 0; --i)    {        //交换堆顶元素H[0]和堆中最后一个元素        int temp = H[i]; H[i] = H[0]; H[0] = temp;        //每次交换堆顶元素和堆中最后一个元素之后,都要对堆进行调整        HeapAdjust(H,0,i);    }}int main(){    int H[10] = {3,1,5,7,2,4,9,6,10,8};    cout<<"初始值:";    print(H,10);    HeapSort(H,10);    //selectSort(a, 8);    cout<<"结果:";    print(H,10);}
1 0
原创粉丝点击