算法:堆排序
Posted 不闻余物
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法:堆排序相关的知识,希望对你有一定的参考价值。
堆排序可归纳为两个操作:
1)建堆:根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大)。
2)调整堆:每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。 当输出完最后一个元素后,这个数组已经是按照从小到大的顺序排列了。调整堆的过程是:比较节点i和左右节点,选出三者最大的,如果是孩子节点,那么交换;并继续比较。
建大根堆:buildMaxHeap(a[])
从A.length / 2一直到根结点进行堆调整。
堆调整:adjustHeap(a[], parent, length);
- 定义左孩子child = 2 * parent + 1;tmp保存父节点;
- 当child < length 的时候:
- 如果有右孩子并且右孩子大于左孩子,则选取右孩子;(选择孩子中较大的;)
- 如果父节点值>孩子节点 break;(父>子,调整完毕;)
- 孩子节点的值赋给父节点;(调整父和孩子;)
- 孩子index赋给父index;并继续child的孩子index赋给孩子index(继续向下调整;)
- tmp赋给最后的父节点;(找到调整值得最终位置;)
堆排序:heapSort(a[])
- 建最大堆;
- for(i=n-1)循环n-1次,交换首尾;adjustHeap(a, 0, i);
辅助交换:swap(a[], i, j)
参考代码:
public class Solution { /** * @param A an integer array * @return void */ //堆排序 public void sortIntegers(int[] a) { if (a.length == 0) return; buildMaxHeap(a); for (int i = a.length - 1; i > 0; i--) { swap(a, i, 0); adjustHeap(a, 0, i); } } public void buildMaxHeap(int[] a) { for (int i = a.length/2; i >= 0; i--) { adjustHeap(a, i, a.length); } } public void adjustHeap(int[] a, int parent, int length) { int tar = a[parent]; int child = parent * 2 + 1; while (child < length) { if (child + 1 < length && a[child] < a[child + 1]) child++; if (a[child] < tar) break; a[parent] = a[child]; parent = child; child = child * 2 + 1; } a[parent] = tar; } public void swap (int[] a, int i, int j) { int tmp = a[i]; a[i] = a[j]; a[j] = tmp; } }
- adjustHeap(a, parent, length):
- tar值保存a[parent];定义child;
- 当chile<length:
- 获取左右孩子中较大的:若存在右孩子且大于左孩子则child++;
- 比较child和tar:若已经满足[tar]>[child]则break;
- child值赋给parent:注意这里是赋值而不是swap;
- 继续向下调整:parent变化,child变化;
- tar值赋给最终的a[parent];
- buildMaxHeap(a):
- for(i=a.length/2; i>=0),adjustHeap(a,i,a.length);注意参数是length;循环范围是[0,a.length/2];
- heapSort(a):
- 判断空return;
- 建堆buildHeap(a); 循环n-1次调整堆for(i=a.length-1; i>0); 循环范围是(0,length-1]n-1次;
- swap(a,i,0);
- adjustHeap(a,0,i) length的范围是[0,n-1]也就是i;
- swap(a[],i,j);
参考:堆排序
以上是关于算法:堆排序的主要内容,如果未能解决你的问题,请参考以下文章