第四周上:Priority Queue

4.1 Priority Queues

1. Priority Queues

  1. 区分:

    • Stack: 最后添加的item,最先被删(LIFO)
    • Queue:最早添加的item,最先被删(FIFO)
    • Randomized queue:随机删除一个item
    • Priority queue:删除最大(或最小)的item
  2. 思路:

    • Plan A :先不排序,insert后就放在序列尾;要remove时,找出最大的删除
    • Plan B:每insert一个,就按升序排一次序;要remove时,直接删除最后一个
  3. Performance

    implementation insert delMax max
    Plan A:Unordered array 1 N N
    Plan B:ordered array N 1 1
  4. Java Implementation(Plan A)

    public class UnorderedMaxPQ>{
      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

  1. complete tree

    • 除了最底层,其他都完全对称

    • N个节点,高度:[lgN]

  2. 思路

    • Array代表了一个heap-ordered complete binary tree
      • heap-ordered complete binary tree
        • Keys在各个Nodes
        • Parent‘s key不能小于children’s key
      • Array
        • 让indices从1开始
        • Nodes按层排序
    • array[1]就是最大的key,即为binary tree的root
    • 对于array[k]
      • Parent: array[k/2]
      • Children: array[2k],array[2k+1]
  3. Performance

    implementation insert delMax max
    Plan A:Unordered array 1 N N
    Plan B:ordered array N 1 1
    Binary heap lgN lgN 1
  4. Java implementation

    public class MaxPQ>{
     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

  1. 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

  1. 思路:

    • 开始有一个无序的array

    • 建一个有n个keys的max-heap(依然假设index是从1到n)

    • 不断地取出最大的key

  2. Performance

    • Heap construction : compares and exchanges
    • Heapsort: compares and exchanges
  3. 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;
     }
    }
    
  1. 总结(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

你可能感兴趣的:(第四周上:Priority Queue)