4.1 Priority Queues
1. Priority Queues
-
区分:
- Stack: 最后添加的item,最先被删(LIFO)
- Queue:最早添加的item,最先被删(FIFO)
- Randomized queue:随机删除一个item
- Priority queue:删除最大(或最小)的item
-
思路:
- Plan A :先不排序,insert后就放在序列尾;要remove时,找出最大的删除
- Plan B:每insert一个,就按升序排一次序;要remove时,直接删除最后一个
-
Performance
implementation insert delMax max Plan A:Unordered array 1 N N Plan B:ordered array N 1 1 -
Java Implementation(Plan A)
public class UnorderedMaxPQ<Key extends Comparable<Key>>{ private Key[] pq; private int n; // number of elements on pq // create an empty priority queue public UnorderedMaxPQ(int capacity){ // no generic array creation pq = (Key[]) new Comparable[capacity]; } // insert a key into the priority queue public void insert(Key v){ pq[n++] = x; } // return and remove the largest key public Key delMax(){ int max = 0; for(int i = 1; i < n; i++){ if(less(pq, max, i)){ max = i; } } exch(pq, max, n-1); return pq[--n]; // null out entry to prevent loitering } public Key max(){ int max = 0; for(int i = 1; i < n; i++){ if(less(pq, max, i)){ max = i; } } return pq[max]; } // is the priority queue empty? public boolean isEmpty(){ return n == 0; } private static boolean less(Comparable a, int i, int j){ return a[i].CompareTo(a[j]) < 0; } private static void exch(Comparable[] a, int i, int j){ Comparable swap = a[i]; a[i] = a[j]; a[j] = swap; } }
2. Binary heaps
-
complete tree
除了最底层,其他都完全对称
N个节点,高度:[lgN]
-
思路
- Array代表了一个heap-ordered complete binary tree
- heap-ordered complete binary tree
- Keys在各个Nodes
- Parent‘s key不能小于children’s key
- Array
- 让indices从1开始
- Nodes按层排序
- heap-ordered complete binary tree
- array[1]就是最大的key,即为binary tree的root
- 对于array[k]
- Parent: array[k/2]
- Children: array[2k],array[2k+1]
- Array代表了一个heap-ordered complete binary tree
-
Performance
implementation insert delMax max Plan A:Unordered array 1 N N Plan B:ordered array N 1 1 Binary heap lgN lgN 1 -
Java implementation
public class MaxPQ<Key extends Comparable<Key>>{ private Key[] pq; private int n; public MaxPQ(int capacity){ pq = (Key[]) new Comparable[capacity+1]; // 因为我们假设从1开始,所以capacity需要+1 } public boolean isEmpty(){ return n == 0; } public void insert(Key key){ // at most 1+lgN compares pq[++n] = x; swim(n); } public Key delMax(){ // at most 2lgN compares Key max = pq[1]; exch(1, n); sink(1); pq[n] = null; n--; return max; } // Child's key变得比它的parent‘s key大 private void swim(int k){ while(k>1 && less(k/2, k)){ exch(k/2, k); k = k/2; } } // Parent's key 变得比它的其中一个child或者比两个children都小 private void sink(int k){ while(2*k <= n){ int j = 2*k; if(j < n && less(j, j+1)){ //找出两个children中较大的那个 j++; } if(!less(k, j)){// parent和较大的那个child比较 break; } exch(k, j); k = j; } } private static boolean less(int i, int j){ return pq[i].CompareTo(pq[j]) < 0; } private static void exch(int i, int j){ Key swap = pq[i]; pq[i] = pq[j]; pq[j] = swap; } }
3. Immutability
-
immutable data type: 一旦创建,data type value不能改变
-
immutable:String, Integer,Double,Vector
// can't override instance methods public final class Vector{ // all instance variable private and final private final int n; private final double[] data; public Vector(double[] data){ this.n = data.length; this.data = new double[n]; for(int i = 0; i < n; i++){ this.data[i] = data[i]; } } // instance methods don't change instance variable ... }
-
- mutable:StringBuilder,Stack,Counter,Java array
4. Heapsort
-
思路:
开始有一个无序的array
建一个有n个keys的max-heap(依然假设index是从1到n)
不断地取出最大的key
-
Performance
- Heap construction : compares and exchanges
- Heapsort: compares and exchanges
-
Java implementation
public class Heap{ public static void sort(Comparable[] a){ // 假设 array 0 到 1 int n = a.length; for(int k = k/2; k >=1; k--){ sink(a, k, n); } while(n > 1){ exch(a, 1, n); sink(a, 1, --n); } } private static void sink(Comparable[] a, int k, int n){ while(2*k <= n){ int j = 2*k; if(j < n && less(a, j, j+1)){ //找出两个children中较大的那个 j++; } if(!less(a, k, j)){// parent和较大的那个child比较 break; } exch(a, k, j); k = j; } } private static boolean less(Comparable[] a, int i, int j){ // 注意:是1-based indexing return a[i-1].CompareTo(a[j-1]) < 0; } private static void exch(Comparable[] a, int i, int j){ // // 注意:是1-based indexing Key swap = pq[i-1]; pq[i-1] = pq[j-1]; pq[j-1] = swap; } }
-
总结(Sorting algorithms)
inplace? stable? worst average best remarks selection √ N exchanges insertion √ √ 适用small N或partially ordered shell √ ? ? code少 quick √ probabilistic guarantee(用shuffle),fastes in practice 3-way quick √ 对quicksort的改良,适用于有很多duplicate keys merge √ guarantee,stable heap √ guarantee,inplace