堆排序

按照书上的定义:堆是一个完全二叉树,且二叉树中的任意一个非叶子结点值都大于(小于)左右孩子结点值。利用这个原理可确定堆中的根节点为最大(小)值。

堆排序的思想:堆采用顺序存放。当用数组建立一个堆后,将堆中的根节点与堆的最后一个元素互换位置,即将最大(小)值输出,然后把除了最后一个元素以外的数组再构建成堆,再把此时堆中根节点与堆的最后一个元素互换位置(是堆,不是数组)。再不断循环此步骤即可实现有序。

 

思路中提到两个步骤:把数组构建成堆,将堆中的根节点与堆的最后一个元素互换位置。用代码实现这两个步骤即可实现堆排序。

先给出堆的示例图:

 

下图为构建堆的图解:

 

以上图为例,把97和38互换位置后,就要对除了97以外的数重新构建成堆。然后不断循环此步骤。

 1 void run(vector<int>& arr, int root, int curr) {//root是当前子树的根节点,curr是当前范围,因为最后面的是已经排好序的了。
 2     int i = root, j = i * 2;                    // j是左孩子
 3     while (j <= curr) {                            //子结点必须在当前范围
 4         if (j < curr && arr[j] < arr[j + 1])
 5             j++;                                //选出左右孩子结点中较大的    
 6         if (arr[i] < arr[j]) {                    //如果父节点小于孩子结点
 7             swap(arr[i], arr[j]);                //就互换
 8             i = j;                                //向下循环
 9             j = i * 2;                            //进入孩子结点的孩子结点
10         }
11         else                                    //如果父节点大于子节点就结束循环
12             break;
13     }
14 }
15 
16 void CreateHeap(vector<int>& arr, int curr) {
17     for (int i = curr / 2; i > 0; i--)
18         run(arr, i, curr);
19 }
20 
21 void HeapSort(vector<int>& arr) {
22     for (int i = arr.size()-1; i>=1; i--) {
23         CreateHeap(arr, i);
24         swap(arr[1], arr[i]);                    //使根节点与堆中最后一个元素互换
25     }
26 }
posted @ 2018-12-11 17:43  捞的不谈  阅读(329)  评论(0编辑  收藏  举报