C++ 堆排序(HeapSort)

一、思路:

   (1)将数组arr[0n-1]调整形成最大堆;

   (2)取堆顶点(即取最大值)放到数组arr[n-1]的位置,即将arr[0]arr[n-1]交换位置;

   (3)调整arr[0]arr[n-2]重新形成最大堆;

   (4)同理,取堆顶arr[0](即取最大值)放到数组arr[n-2]位置,即交换arr[0]arr[n-2]位置;

   (5)重复以上步骤,这样从数组arr[n-1]->arr[0]是第一大,第二大,…,就是从小到大排序;(同理:从大到小,就用最小堆实现)

 

二、实现程序:

#include <iostream>
using namespace std;

const int maxSize = 100;

template <class T>
void HeapSort(T arr[], int n); // 堆排序

template <class T>
void ShiftDown(T arr[], int start, int end); // 下滑

int main(int argc, const char * argv[]) {
    int i, n, arr[maxSize];
    
    cout << "请输入要排序的数的个数:";
    cin >> n;
    cout << "请输入要排序的数:";
    for(i = 0; i < n; i++)
        cin >> arr[i];
    cout << "排序前:" << endl;
    for(i = 0; i < n; i++)
        cout << arr[i] << " ";
    cout << endl;
    HeapSort(arr, n);
    cout << "排序后:" << endl;
    for(i = 0; i < n; i++)
        cout << arr[i] << " ";
    cout << endl;
    return 0;
}

// 堆排序
template <class T>
void HeapSort(T arr[], int n) {
    int CurrentPos, i, temp; // CurrentPos当前下滑结点
    
    // 第一步:第1次形成最大堆,(n / 2 - 1)为倒数第一个非叶结点
    for(CurrentPos = (n / 2 - 1); CurrentPos >= 0; CurrentPos--)
        ShiftDown(arr, CurrentPos, n-1);
    // 第二步:取堆顶点(即最大值)放到n-1位置:交换arr[0]与arr[n-1]
    temp = arr[0];
    arr[0] = arr[n-1];
    arr[n-1] = temp;
    for(i = n-2; i > 0; i--) { // 第2次形成最大堆
        // 第三步:将剩下的数arr[0 ~ n-2]重新调整最大堆
        ShiftDown(arr, 0, i); // 每次只是调整刚交换的arr[0]就可以了
        temp = arr[0];
        arr[0] = arr[i];
        arr[i] = temp;
    }
}

// 下滑
template <class T>
void ShiftDown(T arr[], int start, int end) {
    int i, j, temp;
    
    i = start;
    j = 2 * i + 1; // j是i的子女
    temp = arr[i];
    while(j <= end) {
        if(j < end && arr[j] < arr[j+1]) // 选两个子女中较大者
            j++;
        if(temp < arr[j]) { // 如果双亲比子女小,则上移子女结点
            arr[i] = arr[j];
            i = j; // 父
            j = 2 * i + 1; // 子女
        } else // 否则,则结束循环
            break;
    }
    arr[i] = temp; // 把arr[0]暂存的值填到当前位置
}

测试数据:

7

20 12 50 70 2 8 40

猜你喜欢

转载自blog.csdn.net/chuanzhouxiao/article/details/89007472
今日推荐