Introduction To Algorithms Chapter6(Heapsort)

                                                    堆排序

Maintaining the heap property

       MAX-HEAPIFY is an important subroutine for manipulating max-heaps. Its inputs are an array A and an index i into the array. When MAX-HEAPIFY is called, it is assumed that the binary trees rooted at LEFT(i) and RIGHT(i) are max-heaps, but that A[i] may be smaller than its children, thus violating the max-heap property. The function of MAX-HEAPIFY is to let the value at A[i] "float down" in the max-heap so that the subtree rooted at index i becomes a max-heap. 
        MAX-HEAPIFY(A, i)
                1 l ← LEFT(i)
                2 r ← RIGHT(i)
                3 if l ≤ heap-size[A] and A[l] > A[i]
                4    then largest ← l 
                 5    else largest ← i 
                 6 if r ≤ heap-size[A] and A[r] > A[largest] 
                 7    then largest ← r 
                 8 if largest ≠ i 
                 9    then exchange A[i] ↔ A[largest] 
                10         MAX-HEAPIFY(A, largest)

 

     we can characterize the running time of MAX-HEAPIFY on a node of height h as O(h).

Building a heap

     We can use the procedure MAX-HEAPIFY in a bottom-up manner to convert an array A[1...n], where n = length[A], into a max-heap.The elements in the subarray A[(⌊n/2⌋+1)...n] are all leaves of the tree, and so each is a 1-element heap to begin with. The procedure BUILD-MAX-HEAP goes through the remaining nodes of the tree and runs MAX-HEAPIFY on each one.

BUILD-MAX-HEAP(A) 
                1  heap-size[A] ← length[A] 
                2  for i ← ⌊length[A]/2⌋ downto 1 
                3       do MAX-HEAPIFY(A, i)

The heapsort algorithm

The heapsort algorithm starts by using BUILD-MAX-HEAP to build a max-heap on the inpuarray A[1...n], where n = length[A]. Since the maximum element of the array is stored at theroot A[1], it can be put into its correct final position by exchanging it with A[n]. If we now "discard" node n from the heap (by decrementing heap-size[A]), we observe that A[1 ...(n - 1)] can easily be made into a max-heap. The children of the root remain max-heaps, but the new root element may violate the max-heap property. All that is needed to restore the max-heap property, however, is one call to MAX-HEAPIFY(A, 1), which leaves a max-heap in A[(n - 1)]. The heapsort algorithm then repeats this process for the max-heap of size n - 1 down to a heap of size 2.

          HEAPSORT(A) 
                1 BUILD-MAX-HEAP(A) 
                2 for i ← length[A] downto 
                3    do exchange A[1] ↔ A[i
                4       heap-size[A] ← heap
                5       MAX-HEAPIFY(A, 1)

 

                               程序模拟

#include <iostream>

using std::cin;
using std::cout;

unsigned int GetLchild(unsigned int iPos)
{//注:堆排序中的树是完全2叉树,如果父亲节点是iPos那么左孩子是2 * iPos
     return 2 * iPos;
}

unsigned int GetRchild(unsigned int iPos)
{//注:堆排序中的树是完全2叉树,如果父亲节点是iPos那么右孩子是2 * iPos + 1
     return 2 * iPos + 1;
}

void Swap(int &a, int &b)
{//值交换
    int temp = a;
    a = b;
    b = temp;
}

void MaxHeapify(int * iArry, unsigned int iPos)
{//父亲节点和儿子节点比较和交换
    int iLchild = GetLchild(iPos);
    int iRchild = GetRchild(iPos);
    int iLargest = iPos;

    if (iLchild <= iArry[0] && iArry[iLchild] > iArry[iPos]) iLargest = iLchild;
    if (iRchild <= iArry[0] && iArry[iRchild] > iArry[iLargest]) iLargest = iRchild;
    if (iLargest != iPos){
       Swap(iArry[iLargest], iArry[iPos]);
       MaxHeapify(iArry, iLargest);//递归把原iPos的值放到合适的位置
    }
}

void BuildMaxHeap(int * iArry)
{//自底向上建立大顶堆
 //由于是完全2叉树,所以节点 n / 2 + 1到 n 的节点都是叶子节点
 //我们建堆得时候只需要从最后的节点n / 2开始到根节点调整即可
    for (unsigned int iPos = iArry[0] / 2; iPos != 0; --iPos){
      MaxHeapify(iArry, iPos);
    }
}

void HeapSort(int * iArry)
{//进行堆排序,每次把最后一个未排序的跟根节点(最大的)交换
 //实现从小到大排序

    BuildMaxHeap(iArry); //建立大顶堆

    for (unsigned int iPos = iArry[0]; iPos >= 1; --iPos){
       Swap(iArry[1], iArry[iPos]);
       iArry[0]--;
       MaxHeapify(iArry, 1);
    }
}

int main(void)
{
    unsigned int iLen;
    while (cin >> iLen){
    int * iArry = new int [iLen + 1];
    if (iLen == 0) return 0;
    iArry[0] = iLen;
    for (unsigned int i = 1; i <= iLen; ++i) cin >> iArry[i];

      HeapSort(iArry);

    for (unsigned int i = 1; i <= iLen; ++i) cout << iArry[i] << ' ';
      cout << '/n';
      delete []iArry;
    }
    return 0;
}

 

//写的...好烂...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值