堆排序 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;
}

 

posted on 2013-01-11 16:58  zhuyf87  阅读(4375)  评论(0编辑  收藏  举报

导航