堆排序算法

来源:互联网 发布:js移除最后一个子元素 编辑:程序博客网 时间:2024/06/05 05:48

堆排序算法
堆是一个数组,他可以被看成是一个近似的完全二叉树,除了最底层之外,该数是完全充满的。一般的,给定一颗二叉树的一个节点,可以很快的算出它的父、左子、右子节点。
Parent(i)=i/2
Left(i)=i*2
Right(i)=i*2+1

最大堆是指的除了根节点外的所有节点,都满足A(parent(i))>=A(i)。一个堆的高度也就是O(lgn)。一个堆排序算法的基本过程包括:维护最大堆MAX-HEAPIFY,时间复杂度为O(lgn); 构造一个最大堆BUILD-MAX-HEAP;原址排序堆过程HEAPSORT,时间复杂度为O(nlgn)。
维护最大堆
MAX-HEAPIFY用来维护最大的堆,它的输入是一个没有建立好的堆以及一个将要维护的位置。假定在调用它时,该即将维护的位置的左右子树都已经维护好了,但是该节点有可能小于左右子树。因此,需要将它和左右子树的最大值变换顺序,此时,子树也有可能不满足最大堆的条件,依次调用这个过程,使得该节点的子树能满足最大堆的要求。
MAX-HEAPIFY(i)
(MaxValue, MaxInd)=MAX(Right(i),Value(i),Left(i))
If MaxValue > Value(i)
SWAP(MaxValue,Value(i))
MAX-HEAPIFY(MaxInd)
建堆
BUILD-MAX-HEAP:维护最大堆时,假定该即将维护的位置的左右子树都已经维护好了。为了达到这一个假定的条件,可以对初始堆进行从底往上进行调用MAX-HEAPIFY(i)。假定堆的长度为LENGTH,则:
For i = LENGTH/2 : -1 : 1
MAX-HEAPIFY(i)
堆排序算法
通过以上两步,可以建立一个最大堆。堆的最大元素总是在a(1)中。因此,将a(1)取出,并将a(end)放到a(1)所在的位置上,然后对位置1进行维护最大堆,过程如下:
HEAPSORT
For i = LENGTH : -1:2
SWAP a(1) with a(LENGTH)
LENGTH–
MAX-HEAPIFY(1)

void Swap(int *pnA, int *pnB) {     int temp = *pnA;      *pnA = *pnB;    *pnB = temp;}  void MAX_HEAPIFY(int num[] , int thisIndex,int size) {      int minIndex; // 指向左右子节点的最小位置    //如果存在子节点    while (thisIndex * 2 + 1 < size)     {               minIndex = thisIndex * 2 + 1; // 初始化为左子节点        if (thisIndex * 2 + 2 < size) // 如果有右节点          {            if (num[thisIndex * 2 + 1] > num[thisIndex * 2 + 2]) // 取最小的,并更新            {                 minIndex = thisIndex * 2 + 2;            }          }          // 该数和最小者进行比较,         if (num[thisIndex] < num[minIndex])         {            break;//已经排序完毕        }         else        {              Swap(num + thisIndex , num + minIndex);// 交换两个数,让大数往下沉              thisIndex = minIndex; // 更新需要维护的节点        }      }// while }void BUILD_MAX_HEAP(int num[] ,int size) {    int i;    //从最后一个非叶子节点开始,从下往上进行建堆    for (i = size / 2 - 1; i >= 0; i--)     {          MAX_HEAPIFY(num, i,size);// 进行维护该节点的操作    }  }void HEAPSORT(int num[] ,int size){    int i;    int iLength = size;     BUILD_MAX_HEAP(num, size); // 建立最小堆     for (i = iLength - 1; i >= 1; i--)     {          Swap(num, num + i);// 交换          size--;//此时最小的元素在最尾,因此堆的规模减1        MAX_HEAPIFY(num, 0, size);// 维护新的首元素,并进行下滤操作    }}
原创粉丝点击