堆排序 c/c++實現


#include <iostream>

using namespace std;

void Swap(int & left_data, int & right_data)
{
    int auxiliary = left_data;
    left_data = right_data;
    right_data = auxiliary;
}

//----------------------------------------------------------------------------------
// 小頂堆

// 從i開始,到其父節點,父節點的父節點...,依次檢查、調整以符合“小頂堆”的性質
void MinHeapAdjustUp(int data[], int i)
{
    if (i <= 0)
        return;

    int j, auxiliary;

    auxiliary = data[i];
    j = (i - 1) / 2; // 父結點

    while (j >= 0 && i != 0)
    {
        if (data[j] <= auxiliary)
            break;

        data[i] = data[j]; // 較大結點下移,替換它的子結點  
        i = j;
        j = (i - 1) / 2;
    }  

    data[i] = auxiliary;
}

// 向“小頂堆”中添加新的數據
// 每次插入都是將新數據放在數組最后,然后從新插入數據開始,
// 到其父節點,父節點的父節點...,依次檢查、調整以符合“小頂堆”的性質
void MinHeapAddData(int data[], int count, int new_data)
{  
    data[count] = new_data;
    MinHeapAdjustUp(data, count);
}

// 從i節點開始,進行一次從上向下的“小頂堆”調整
// count為節點總數,i節點的左右孩子節點依次為 2*i+1, 2*i+2  
void MinHeapAdjustDown(int data[], int i, int count)
{
    int j, auxiliary;

    auxiliary = data[i];
    j = 2 * i + 1; // 左孩子結點

    while (j < count)
    {
        if (j + 1 < count && data[j + 1] < data[j]) // 在左右孩子中找最小的
            j++;

        if (data[j] >= auxiliary)
            break;

        data[i] = data[j]; // 把較小的子結點往上移動,替換它的父結點
        i = j;
        j = 2 * i + 1;
    }

    data[i] = auxiliary;
}

// 從“小頂堆”中刪除數據
// 堆中每次都只能刪除第0個數據。為便於重建堆,將最后一個數據的值賦給根結點
// 然后再從根結點開始進行一次從上向下的調整
void MinHeapDeleteData(int data[], int count)
{
    Swap(data[0], data[count - 1]);
    MinHeapAdjustDown(data, 0, count - 1);
}

// 建立“小頂堆”
// 因為對葉子結點來說,它已經是一個合法的“小頂堆”
// 所以這里只需要,從下往上,從右到左,將每個“非葉結點”當作根結點,將其與其子樹調整成“小頂堆”
void MakeMinHeap(int data[], int count)
{
    for (int i = count / 2 - 1; i >= 0; i--)
        MinHeapAdjustDown(data, i, count);
}

// 堆排序(利用小頂堆,進行降序排序)
void MinHeapSortDesc(int data[], int count)
{
    for (int i = count - 1; i >= 1; i--)
    {
        Swap(data[i], data[0]);
        MinHeapAdjustDown(data, 0, i);
    }
}

//----------------------------------------------------------------------------------
// 大頂堆

// 從i開始,到其父節點,父節點的父節點...,依次檢查、調整以符合“大頂堆”的性質
void MaxHeapAdjustUp(int data[], int i)
{
    if (i <= 0)
        return;

    int j, auxiliary;

    auxiliary = data[i];
    j = (i - 1) / 2; // 父結點

    while (j >= 0 && i != 0)
    {
        if (data[j] >= auxiliary)
            break;

        data[i] = data[j]; // 較小結點下移,替換它的子結點  
        i = j;
        j = (i - 1) / 2;
    }  

    data[i] = auxiliary;
}

// 向“大頂堆”中添加新的數據
// 每次插入都是將新數據放在數組最后,然后從新插入數據開始,
// 到其父節點,父節點的父節點...,依次檢查、調整以符合“大頂堆”的性質
void MaxHeapAddData(int data[], int count, int new_data)
{  
    data[count] = new_data;
    MaxHeapAdjustUp(data, count);
}

// 從i節點開始,進行一次從上向下的“大頂堆”調整
// count為節點總數,i節點的左右孩子節點依次為 2*i+1, 2*i+2  
void MaxHeapAdjustDown(int data[], int i, int count)
{
    int j, auxiliary;

    auxiliary = data[i];
    j = 2 * i + 1; // 左孩子結點

    while (j < count)
    {
        if (j + 1 < count && data[j + 1] > data[j]) // 在左右孩子中找最大的
            j++;

        if (data[j] <= auxiliary)
            break;

        data[i] = data[j]; // 把較大的子結點往上移動,替換它的父結點
        i = j;
        j = 2 * i + 1;
    }

    data[i] = auxiliary;
}

// 從“大頂堆”中刪除數據
// 堆中每次都只能刪除第0個數據。為便於重建堆,將最后一個數據的值賦給根結點
// 然后再從根結點開始進行一次從上向下的調整
void MaxHeapDeleteData(int data[], int count)
{
    Swap(data[0], data[count - 1]);
    MaxHeapAdjustDown(data, 0, count - 1);
}

// 建立“大頂堆”
// 因為對葉子結點來說,它已經是一個合法的“大頂堆”
// 所以這里只需要,從下往上,從右到左,將每個“非葉結點”當作根結點,將其與其子樹調整成“大頂堆”
void MakeMaxHeap(int data[], int count)
{
    for (int i = count / 2 - 1; i >= 0; i--)
        MaxHeapAdjustDown(data, i, count);
}

// 堆排序(利用小頂堆,進行降序排序)
void MaxHeapSortAsc(int data[], int count)
{
    for (int i = count - 1; i >= 1; i--)
    {
        Swap(data[i], data[0]);
        MaxHeapAdjustDown(data, 0, i);
    }
}

int main()
{
    int array[] = {9, 6, 3, 8, 7, 1, 5, 2, 4};

    MakeMinHeap(array, 9);
    MinHeapSortDesc(array, 9);

    for(int i = 0; i < 9; ++i)
        cout << array[i] << " ";

    cout << endl;

    MakeMaxHeap(array, 9);
    MaxHeapSortAsc(array, 9);

    for(int i = 0; i < 9; ++i)
        cout << array[i] << " ";

    cout << endl;

    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM