数据结构基础加强之最小堆的实现与堆排序
2017-05-16 19:15
489 查看
数据结构基础加强之最小堆的实现与堆排序
二叉堆的形式:
最小堆:根结点的值是所有堆结点中最小者,并且每个结点的值比其孩子结点小。
最大堆:根结点的值是所有堆结点中最大者,并且每个结点的值比其孩子结点大。
最小堆通常都是一棵完全二叉树,可以用数组来存储最小堆的值。
堆中父结点与子结点 的关系:
heap[father * 2] = heap[leftChild]; heap[father * 2 + 1] = heap[rightChild];
最大堆与最小堆基本做法基本一致,只要把实现代码中的小于变大于,大于变小于即可。
最小堆的初始化:依次将节点加入堆数组中,每次进入新的结点加到堆数组的尾部,依次与父结点相比较,如果小于父结点则交换二者的位置。
最小堆的调整:一处最小堆的根节点之后,需要调整堆数组使之成为一个新的堆。
可以采用以下方式来调整堆:将堆数组最后一个元素放到堆数组的首部,依次与左右子结点比较,把较小的值与根节点交换,然后递归,直至当前节点是叶子节点为止。
堆排序的实现:
利用建立的堆实现堆排序比较简单。将数组中的元素依次加入最小堆中,每次取出堆数组的第一个元素,即最小值放到待排序数组的首部。每次取出堆数组第一个元素后,堆数组会自己调整,让它继续是一个最小堆。依次取出最数组的中的第一个元素,依次放入待排序数组中,直至堆数组为空,此时待排序数组是有序的。
堆排序实现代码:
二叉堆的形式:
最小堆:根结点的值是所有堆结点中最小者,并且每个结点的值比其孩子结点小。
最大堆:根结点的值是所有堆结点中最大者,并且每个结点的值比其孩子结点大。
最小堆通常都是一棵完全二叉树,可以用数组来存储最小堆的值。
堆中父结点与子结点 的关系:
heap[father * 2] = heap[leftChild]; heap[father * 2 + 1] = heap[rightChild];
最大堆与最小堆基本做法基本一致,只要把实现代码中的小于变大于,大于变小于即可。
最小堆的初始化:依次将节点加入堆数组中,每次进入新的结点加到堆数组的尾部,依次与父结点相比较,如果小于父结点则交换二者的位置。
//添加元素 public void add(int item){ size++; heap[size] = item; int curr = size; while (heap[curr] < heap[getFather(curr)]) { swap(curr,getFather(curr)); curr = getFather(curr); } }
最小堆的调整:一处最小堆的根节点之后,需要调整堆数组使之成为一个新的堆。
可以采用以下方式来调整堆:将堆数组最后一个元素放到堆数组的首部,依次与左右子结点比较,把较小的值与根节点交换,然后递归,直至当前节点是叶子节点为止。
//元素下移调整 public void pushDown(int pos){ int smallChild; while (!isLeaf(pos)) { smallChild = getLeftChild(pos); //在父节点知道的情况下,左节点不会出现越界情况,右节点可能越界 if (smallChild <= size) { if (getRightChild(pos) <= size && heap[smallChild] > heap[smallChild + 1]) { smallChild++; } if (heap[pos] > heap[smallChild]) { swap(pos,smallChild); pos = smallChild; }else { return; } }else { return; } } }
堆排序的实现:
利用建立的堆实现堆排序比较简单。将数组中的元素依次加入最小堆中,每次取出堆数组的第一个元素,即最小值放到待排序数组的首部。每次取出堆数组第一个元素后,堆数组会自己调整,让它继续是一个最小堆。依次取出最数组的中的第一个元素,依次放入待排序数组中,直至堆数组为空,此时待排序数组是有序的。
堆排序实现代码:
import heap.Heap; public class HeapSort { public static void main(String[] args) { int[] array = { 1, 9, 6, 8, 7, 3, 4, 2, 0 }; solution(array); for (int i : array) { System.out.print(i + " "); } } private static void solution(int[] array) { Heap heap = new Heap(10); for (int i : array) { heap.add(i); } for (int i = 0;i < array.length;i++) { array[i] = heap.delete(); } } }最小堆的实现代码:
public class Heap { private int[] heap; private int size;//当前节点数 @SuppressWarnings("unused") private int max; //最大节点数 //使用数组存储堆元素 根节点位于数组下表为1的元素 public Heap(int max){ this.max = max; heap = new int[max]; size = 0; heap[0] = Integer.MIN_VALUE; } //获得父节点的位置 public int getFather(int index){ return index / 2; } //获得左子节点的位置 public int getLeftChild(int index){ return index * 2; } //获得右子节点的位置 public int getRightChild(int index){ return index * 2 + 1; } //判断节点是否为根节点 public boolean isLeaf(int index){ if (index > size / 2 && index < size) { return true; }else{ return false; } } //判断堆是否为空 public boolean isEmpty(){ if (size == 0) { return true; }else{ return false; } } //元素交换 public void swap(int pos1,int pos2){ int temp = heap[pos1]; heap[pos1] = heap[pos2]; heap[pos2] = temp; } //打印所有节点 public void print(){ for (int i = 1;i <= size;i++) { System.out.print(heap[i] + " "); } } //添加元素 public void add(int item){ size++; heap[size] = item; int curr = size; while (heap[curr] < heap[getFather(curr)]) { swap(curr,getFather(curr)); curr = getFather(curr); } } //删除并返回根节点 public int delete(){ int firstItem = heap[1]; swap(1, size); size--; if (size != 1) { pushDown(1); } return firstItem; } //元素下移调整 public void pushDown(int pos){ int smallChild; while (!isLeaf(pos)) { smallChild = getLeftChild(pos); //在父节点知道的情况下,左节点不会出现越界情况,右节点可能越界 if (smallChild <= size) { if (getRightChild(pos) <= size && heap[smallChild] > heap[smallChild + 1]) { smallChild++; } if (heap[pos] > heap[smallChild]) { swap(pos,smallChild); pos = smallChild; }else { return; } }else { return; } } } }具体代码可以参考:https://github.com/Li-JY/algorithm-and-datastructure/tree/master/src/heap
相关文章推荐
- 数据结构基础 之 二叉堆实现堆排序
- 数据结构基础(1)--数组C语言实现--动态内存分配(跟风追逐,加强突击)
- 四、数据结构基础之链栈C语言实现
- 【数据结构与算法基础】以数组实现的循环队列 / Circular Queue implemented by array
- 【数据结构与算法】【排序】堆排序的代码实现
- 数据结构基础(7) --循环队列的设计与实现
- 数据结构基础java实现—双向链表
- 数据结构基础(一)栈的实现
- 算法与数据结构基础3:C++单链表类的简单实现
- 数据结构基础(三)哈希表的实现
- 数据结构基础(6) --顺序栈的设计与实现
- 三、数据结构基础之顺序栈C语言实现
- 数据结构之数组实现基础队列结构
- hrbustoj 1545:基础数据结构——顺序表(2)(数据结构,顺序表的实现及基本操作,入门题)
- 六、数据结构基础之链队列C语言实现
- 算法与数据结构基础4:C++二叉树实现及遍历方法大全
- 七、数据结构基础之顺序串C语言实现
- 数据结构基础系列——单链表的实现
- 数据结构基础系列——链栈的实现
- 算法与数据结构基础8:C++实现有向图——邻接表存储