最大堆排序 C++

堆排序是一种复杂度为O(nlog(n))的一种高效的排序,这里将展示最大堆的排序算法。

堆排序是将数组抽象化成为一个完全二叉树。这里对:A[10]={10,5,13,2,8,12,3,9,7,1}

抽象的二叉树结构如下:

1、下面三个节点是得到左子节点,右子节点,和父节点。

int left(int i)   //返回左儿子

{

    return 2 * i+1;

}

int right(int i)  //返回右儿子

{

    return 2 * i + 2;

}

int parent(int i)  //返回父节点

{

    return (i-1) / 2;

}

比如调用left(1),就是找A[1]的左子节点,就返回3

2、下面这个函数maxHeapIfy是将父节点的数和子节点的数对比,将最大的数移动到父节点上。在调换的子节点作为新的父节点实现相同的操作。如执行maxHeapIfy(A,0),先将右子节点的数13和父节点10进行交换:

被调换的子节点10进行递归调用maxHeapIfy(A,2),于是和左子节点的数进行交换:

代码如下:

void maxHeapIfy(int A[], int i,int n)  //i节点为根的堆中小的数依次上移,n表示堆中的数据个数

{

    int l = left(i);

    int r = right(i);  //i的左儿子,i的右儿子

    int largest;   //记录父节点,子节点三个节点中最大值得位置

    if (l < n&&A[l] > A[i])

         largest = l;

    else largest = i;   //先找出A[i],和他的两个字节点最大值的位置

    if (r < n&&A[r] > A[largest])

         largest = r;

    if (largest != i)    //等于i不用做任何操作

    {

         swap(A[i],A[largest]);

         maxHeapIfy(A, largest, n);  //如果不是交换后的子节点不是以这个子节点为堆的最大值,递归调用。

    }

    return;

}

3、建立最大堆:

在这道题中,依次对821210即是A[4],A[3],A[2],A[1],A[0]调用maxHeapIfy函数,就可以得到最大堆,即是从:

For i=(n-1)/2 to 0:

  maxHeapIfy(A,i)

就可以实现最大堆。

void buildMaxHeap(int A[], int n)  //建立最大堆

{

    for (int i = n / 2-1; i >= 0; i--)  //从(n/2-1)一次调用maxHeapIfy就可以得到最大堆

         maxHeapIfy(A, i, n);

}

最后就是排序的过程,将第一个数踢出来,最后一个数放到第一个上,对剩下的数调用maxheapIfy,就可以得到降序的排列:

void heapSort(int A[], int n)  //堆排序算法

{

    buildMaxHeap(A, n);  //先建立堆

    cout << A[0] << endl;

    for (int i = n-1; i >=0; i--)

    {

         swap(A[0], A[i]);

         maxHeapIfy(A, 0, i);

         cout << A[0] << endl;

    }

}

主函数:

int array[10] = {10,5,13,2,8,12,3,9,7,1 };

    heapSort(array, 10);

结果如下:

猜你喜欢

转载自blog.csdn.net/cysisu/article/details/80002060
今日推荐