堆排序<一> ---------简单结构堆排序

来源:互联网 发布:ubuntu 调整分辨率 编辑:程序博客网 时间:2024/06/05 00:44

堆排序:
利用最大堆/最小堆完成排序
用数组存储,但逻辑结构为 完全二叉树

HeapElem arr[] = {45,23,56,34,12,45,67,78,90};
物理结构:

逻辑结构:

arr[end] = 90
start = (end-1)/2=3
tmp = 34
i = 3 (要调整的结点)
j= i*2+1 (左孩子结点)
对 3 7 8 进行判断,已符合最小堆规则 则不调整 break
arr[i] = tmp;

–pos // 开始循环调整 2位置的 while(pos>=0)



普通结构堆排序

#include <stdio.h>#include <assert.h>typedef int HeapElem ;   // 定义堆排序时数据类型template<class Type>void Swap(Type &a,Type &b)    // 交换函数{    Type tmp = a;    a=b;    b=tmp;}void FileterDown(HeapElem *p,int start,int end)   // 向下调整{    int i = start;             // 调整的分支结点 起始位置    int j = i*2 +1;             // 左孩子    HeapElem tmp = p[i];        // 取出当前元素    while(j<=end)                 // 在end之前    {        if(j < end && p[j]>p[j+1]) j+=1;         // 左右孩子内部判断取最小==》最小堆        if(tmp <= p[j]) break;        p[i] = p[j];         i = j;                          // 向下继续调整        j = i*2+1;    }    p[i] = tmp;                            }void MakeMinHeap(HeapElem *p ,int n){    if(p == NULL || n <2)    {        return ;    }    int end = n-1 ;                         // 找出最后一个结点下标    int pos = (end -1)/2;                   // pos为end的双亲结点    while(pos>=0)                                {        FileterDown(p,pos,end);             //向下调整        --pos;                              // 要调整的位置向上走    }}void Heap_sort(HeapElem *p,int n){    int pos = n-1;    while(pos > 0)    {        Swap(p[0],p[pos]);                 // 用堆顶最小元素  与末尾元素交换        FileterDown(p,0,--pos);            // 继续调整剩余其他元素             }}void PrintHeap(HeapElem *p ,int n){    assert(p != NULL);    for(int i = 0;i<n;++i)    {        printf("%d ",p[i]);           // 打印  从大到小      }    printf("\n");}void main(){    HeapElem arr[] = {45,23,56,34,12,45,67,78,90};    int n = sizeof(arr)/sizeof(arr[0]);    MakeMinHeap(arr,n);    Heap_sort(arr,n);    PrintHeap(arr,n);}

测试结果:

原创粉丝点击