数据结构与算法之优先队列<九>
2017-04-07 17:55
459 查看
什么是优先队列
快速得找到元素的最大或最小值。为了实现这种数据结构
优先队列便孕育而生。优先队列或ADT是一种数据结构,支持插入和删除最小值或最大值并返回最大值或最小值得操作。
优先队列的应用
1.数据压缩(赫夫曼编码)
2.最短路径
3.最小生成树
4.选择问题:查找第K个最小元素
优先队列的实现
1.有序/无序数组实现
2.有序/无序链表实现
3.二叉树实现
4.二叉堆实现
主要介绍二叉堆的实现
二叉堆是一棵具有特殊性质的二叉树。
基本要求是所有节点必须大于或等于(小于或等于)其孩子节点
并且应该是一棵完全二叉树
二叉堆的实现
至此,优先队列的基础介绍完毕。
快速得找到元素的最大或最小值。为了实现这种数据结构
优先队列便孕育而生。优先队列或ADT是一种数据结构,支持插入和删除最小值或最大值并返回最大值或最小值得操作。
优先队列的应用
1.数据压缩(赫夫曼编码)
2.最短路径
3.最小生成树
4.选择问题:查找第K个最小元素
优先队列的实现
1.有序/无序数组实现
2.有序/无序链表实现
3.二叉树实现
4.二叉堆实现
主要介绍二叉堆的实现
二叉堆是一棵具有特殊性质的二叉树。
基本要求是所有节点必须大于或等于(小于或等于)其孩子节点
并且应该是一棵完全二叉树
二叉堆的实现
/* * 优先队列是至少允许下列两种操作的数据结构 * insert(插入) deleteMin(删除最小) * 优先队列的工作是 找出 返回 删除 优先队列中的最小或最大元素 * * 完全二叉堆实现优先队列 * 利用完全二叉树的紧凑性将完全二叉树转化为数组形式 */ public class BinaryHeap<T extends Comparable<? super T>> { // 堆 private T[] heap; // 当前大小 private int currentSize; // 默认大小 private final static int DEFAULT_SIZE = 10; public BinaryHeap() { this(DEFAULT_SIZE); } // 打印二叉堆 public void printHeap() { for (int i = 0; i < currentSize; i++) System.out.print(this.heap[i] + ","); } @SuppressWarnings("unchecked") public BinaryHeap(int size) { heap = (T[]) new Comparable[size]; } // 将一个数组转化为二叉堆 @SuppressWarnings("unchecked") public BinaryHeap(T[] items) { currentSize = items.length; heap = (T[]) new Comparable[(currentSize + 2) * 11 / 10]; System.arraycopy(items, 0, heap, 0, items.length); bulidHeap(); } /* * 对外开放的方法 */ // 插入堆 public void insert(T t) { // 数据临界 扩一倍 if (currentSize == heap.length) enlargeArray(heap.length * 2); // 当前数量加一 currentSize++; // 插入节点的序号 int i = currentSize - 1; while (i > 0 && t.compareTo(heap[(i - 1) / 2]) > 0) { // 插入数据大于其父节点的数据 heap[i] = heap[(i - 1) / 2]; // 下一个父节点 i = (i - 1) / 2; } heap[i] = t; } // 找到最大值 public T findMax() { if (currentSize > 0) return heap[0]; return null; } // 删除最大值 public T deleteMax() { T t = null; if (currentSize > 0) { t = heap[0]; // 将最后一个元素替代第一个 heap[0] = heap[currentSize - 1]; currentSize--; percolateDown(0); } return t; } /* * 私人方法 */ // 下滤 (先找到孩子的最大值在与小于孩子的父节点互换) private void percolateDown(int hole) { // 判断节点是否有孩子 int left = hole * 2 + 1; T temp; // 如果左孩子存在 if (left < currentSize) { // 如果右孩子存在 if (left + 1 < currentSize) { // 若右孩子大于左孩子互换 if (heap[left + 1].compareTo(heap[left]) > 0) { temp = heap[left + 1]; heap[left + 1] = heap[left]; heap[left] = temp; } } // 如果左节点大于父节点 互换 if (heap[left].compareTo(heap[hole]) > 0) { temp = heap[hole]; heap[hole] = heap[left]; heap[left] = temp; } } } // 建立二叉堆 public void bulidHeap() { // 调整所有节点 (currentSize表示当前堆中元素个数) for (int i = (currentSize - 2) / 2; i >= 0; i--) { percolateDown(i); } } // 动态扩充数组变为原来的两倍 @SuppressWarnings("unchecked") private void enlargeArray(int newSize) { // 保存旧数据 T[] temp = heap; // 扩一倍 heap = (T[]) new Comparable[2 * heap.length]; // 导入旧数据 System.arraycopy(temp, 0, heap, 0, temp.length); } }
至此,优先队列的基础介绍完毕。
相关文章推荐
- 数据结构与算法之栈与队列<四>
- 数据结构1:栈、队列、优先队列相关的算法题
- <二>java数据结构与算法 冒泡排序
- 优先队列的实现 Java数据结构与算法
- <四>java数据结构与算法 插入排序
- 数据结构与算法--优先队列和堆排序
- 数据结构与算法之循环链表 <三>
- <六>java数据结构与算法 栈
- 数据结构与算法之基础排序(冒泡/插入/选择)<十>
- 数据结构与算法(3)----->队列和栈
- 数据结构与算法之图的邻接表与邻接矩阵<十二>
- 数据结构与算法之单向链表 <一>
- 数据结构与算法(C语言)<绪论>
- Javascript数据结构与算法--队列(顺序队列、优先队列、循环队列)的实现与用法
- 数据结构与算法之散列(线性/平方/双平方探测法)<八>
- 数据结构与算法之双向链表 <二>
- <七>java数据结构与算法 栈 实现单词逆序
- 数据结构学习笔记<三>数据结构算法2.2具体实现
- <三>java数据结构与算法 选择排序
- 数据结构与算法4——栈和队列