堆(Heap)

Date:2019-05-08 21:27:07

选择排序:

 1 void SelectSort(int A[], int n)
 2 {
 3     for(int i=0; i<n; i++)
 4     {
 5         int k = i;
 6         for(int j=i; j<n; j++)
 7             if(A[j] < A[k])
 8                 k = j;
 9         swap(A[i],A[k]);
10     }
11 }
  • 算法思想:从A[i~n]选择最小的关键字,置于A[i];
  • 接下来介绍的堆排序属于选择排序的一种;

堆的存储:

1 int heap[MAX_SIZE];
  • 采用二叉树的静态存储方式;
  • 结点下标的取值范围【1<= i <= N】;
  • 左孩子下标【i*2】,右孩子下标【i*2+1】;
  • 叶子结点下标【i>= n/2】;

向下调整:

 1 void DownAdjust(int low, int high)
 2 {
 3     int i=low, j=i*2;
 4     while(j <= high)
 5     {
 6         if(j+1<=high && heap[j+1]>heap[j])   //先比较左右孩子的大小
 7             j = j + 1;
 8         if(heap[j] > heap[i])    //孩子大于父亲,则交换(大根堆)
 9         {
10             swap(heap[j], heap[i]);
11             i = j;    //不断向下调整直至叶子结点
12             j = i * 2;  
13         }
14         else
15             break;
16     }
17 }
  • 时间复杂度:O(logN)

堆的建立:

1 void CreateHeap()
2 {  
3     for(int i=n/2; i>=1; i--)  //从最后一个非叶子结点开始,直至根结点            
4     DownAdjust(i, n);       //依次向下调整
5 } 
  • 时间复杂度:O(N*logN)

堆的删除:

1 void DeleteTop()
2 {
3     heap[1] = heap[n--];    //最后一个元素替代堆顶
4     DownAdjust(1,n);        //向下调整堆顶元素
5 }
  • 时间复杂度:O(logN)

向上调整:

void UpAdjust(int low, int high)
{
    int i=high, j=i/2;
    while(j>=low)
    {
        if(heap[j] < heap[i])  //孩子大于父亲,则交换(大根堆)
        {
            swap(heap[j], heap[i]);
            i = j;
            j /= 2;
        }
        else
            break;
    }
}
  • 时间复杂度:O(logN)

堆的插入:

1 void Insert(int x)
2 {
3     heap[++n] = x;  //末尾插入结点
4     UpAdjust(1,n);  //向上调整
5 }
  • 时间复杂度:O(logN)

堆排序:

1 void HeapSort()
2 {
3     CreateHeap();
4     for(int i=n; i>1; i--)
5     {
6         swap(heap[i], heap[1]);
7         DownAdjust(1,i-1);
8     }
9 }
  • 时间复杂度:O(N*logN)

 Attention:

  • priority_queue也是用堆来实现的
posted @ 2019-05-08 21:41  林東雨  阅读(342)  评论(0编辑  收藏  举报