• 堆排序


    堆是一棵完全二叉树,其任一非叶结点的关键字不小于(最大堆而言)或不大于(最小堆而言)其左右孩子节点的关键字。

    假设待排序数组为A[],那么初始的话我们可以按层次编号建树,对结点i(从零开始)而言,其左右结点分别为2*i+1、2*i+2。

    堆排序的算法可大致描述如下:

    1.建立最大堆(或最小堆);

    2.

    for(i = heapSize -1; i > 0; i --)
    {
        swap(A[i], A[0]);
        heapSize --;
        RestoreHeap(A, 0);           
    }

    堆排序整体代码如下:

     1 #include <iostream>
     2 #include <cstdlib>
     3 using namespace std;
     4 int heapSize;
     5 void swap(int &a, int &b)
     6 {
     7     int temp = a;
     8     a = b;
     9     b = temp;
    10 }
    11 void RestoreHeap(int *A, int i)
    12 {
    13     int l = 2*i + 1;
    14     int r = 2*i + 2;
    15     int great;
    16     if(l < heapSize && A[l] > A[i])
    17         great = l;
    18     else 
    19         great = i;
    20     if(r < heapSize && A[r] > A[great])
    21         great = r;
    22     if (great != i)
    23     {
    24         swap(A[i], A[great]);
    25         RestoreHeap(A, great);
    26     }
    27 }
    28 //非递归Restore算法
    29 void Restore(int *A, int i)
    30 {
    31     int j = i;
    32     int l, r, great;      
    33     while(j <= heapSize/2 - 1)
    34     {
    35         l = 2*j + 1;
    36         r = 2*j + 2;
    37         if(r < heapSize && A[l] < A[r])
    38             great = r;
    39         else 
    40             great = l;
    41         if(A[great] > A[j])
    42         {
    43             swap(A[great], A[j]);
    44             j = great;
    45         }
    46         else
    47             break;
    48     }
    49 }
    50 void BuildMaxHeap(int *A)
    51 {
    52     for(int i = heapSize/2 - 1; i >= 0; i--)
    53         //RestoreHeap(A, i);
    54         Restore(A, i);
    55 }
    56 void HeapSort(int *A)
    57 {
    58     BuildMaxHeap(A);
    59     for(int i = heapSize - 1; i > 0; i--)
    60     {
    61         swap(A[i], A[0]);
    62         heapSize --;
    63         //RestoreHeap(A, 0);
    64         Restore(A, 0);
    65     }
    66 }
    67 int main()
    68 {
    69     int *A = NULL;
    70     cout<<"Input heap size and its values:"<<endl;
    71     while(cin>>heapSize && heapSize)
    72     {
    73         try
    74         {
    75             A = new int[heapSize];
    76         }
    77         catch(const bad_alloc &e)
    78         {
    79             cerr<<"bad alloc error:"<<e.what()<<endl;
    80             abort();
    81         }
    82         int i;
    83         for(i = 0; i < heapSize; i++)
    84         {
    85             cin>>A[i];
    86         }
    87         int size = heapSize;
    88         HeapSort(A);
    89         cout<<"After sort:"<<endl;
    90         for(i = 0; i < size; i++)
    91             cout<<A[i]<<" ";
    92         cout<<endl<<"Input heap size and its values:"<<endl;
    93         delete A;
    94         A = NULL;
    95     }
    96     return 0;
    97 }

    堆排序是不稳定的排序,因为在重建堆的时候并没有考虑原来的顺序,即便关键字相同的元素也有可能进行交换。

    如原创文章,转载请注明:转自http://www.cnblogs.com/xpowerlord/
  • 相关阅读:
    考试 题目
    引用数据类型 Scanner和 Random
    数组
    数据字典 事物 序列 索引视图
    小程序下拉刷新
    使用e.target.dataset的问题
    动态统计当前输入内容的字节、字符数
    小程序根据input输入,动态设置按钮的样式
    小程序刨坑(一)
    charles 踩坑记录
  • 原文地址:https://www.cnblogs.com/xpowerlord/p/3713478.html
Copyright © 2020-2023  润新知