1. 程式人生 > >演算法學習筆記之——priority queue、heapsort、symbol table、binary search trees

演算法學習筆記之——priority queue、heapsort、symbol table、binary search trees

Priority Queue

類似一個Queue,但是按照priority的大小順序來出隊 一般存在兩種方式來實施

  1. 排序法(ordered),在元素入隊時即進行排序,這樣插入操作為O(N),但出隊為O(1)
  2. 不排序法(unordered),元素直接插入到後面,出隊時先排序後提取,插入操作為O(1),出隊為O(N)

採用二叉樹

用佇列模擬二叉樹,root為a[1],子元素為a[2k]或a[2k+1] 父元素總是比子元素要大,提取max為a[1] 不符合規則的子元素(其value比父元素大)可以不斷與父元素交換,直至符合要求;不符合規則的父元素(其value比子元素小)可不斷與子元素中最大的元素交換,直至符合要求 插入操作:將元素插入到樹的右下角,然後保證該元素符合要求 刪除操作:將root與最後的元素對換,提出root,再將新的root規則化(下移)直至符合要求 刪除與插入都是O(lg(N))

應用例項:基於事件的模擬(Event driven simulation)

堆排序(heapsort)

1. 將陣列視為完全二叉樹
2. 將二叉樹從底往上構建maxheap,最終二叉樹滿足父元素不小於子元素
3. 將根元素(最大值)與最後的元素交換,並根元素出隊(array的size-1),並將新的root下沉至符合要求
4. 重複3的操作直至根元素,即完成從小到大的排列

堆排序的操作時間與記憶體消耗都是角優的,為O(lg(N)),但是操作時間還是小於quicksort,而且排序是不穩定的(not stable)

符號表(symbol table)

Symbol table stores the information related about the symbol.

符號表將符號與其值對應起來,可以通過符號獲取與更新其值,例如傳遞URL到DNS伺服器來獲取IP地址。

public class ST<Key extends Comparable<Key>, Value>
--------------------------------------------------------
ST()                                create an ordered symbol table
void put(Key key, Value val)        put key-value pair into the table
Value get(Key key)                  value paired with key
void delete(Key key)                remove key (and its value) from table
boolean contains(Key key)           is there a value paired with key?
boolean isEmpty()                   is the table empty?
int size()                          number of key-value pairs
Key min()                           smallest key
Key max()                           largest key
Key floor(Key key)                  largest key less than or equal to key
Key ceiling(Key key)                smallest key greater than or equal to key
int rank(Key key)                   number of keys less than key
Key select(int k)                   key of rank k
void deleteMin()                    delete smallest key
void deleteMax()                    delete largest key
int size(Key lo, Key hi)            number of keys in [lo..hi]
Iterable<Key> keys(Key lo, Key hi)  keys in [lo..hi], in sorted order
Iterable<Key> keys()                all keys in the table, in sorted order
implementation search(GAC) insert(GAC) search(AVC) insert(AVC) ordered ops? operations on keys
sequential search(unordered list) N N N/2 N no equals()
binary search (ordered array) lg(N) N lg(N) N/2 yes compareTo()
BST N N 1.39lg(N) 1.39lg(N) next compareTo()

GAC: Guarantee average case AVC: Average case BST: Binary search trees

二叉排序樹BST(Binary search trees)

一個BST要麼為空,要麼同時有左子樹與右子數,字數可以為null 每個節點的key大於所有左子樹元素,但是小於所有右子樹的元素

插入操作程式如下,通過遞迴返回更新的子樹來代替原來的樹

public void put(Key key, Value val){    
    root = put(root, key, val); }

private Node put(Node x, Key key, Value val){
    if (x == null) return new Node(key, val);
    int cmp = key.compareTo(x.key);
    if (cmp < 0)
        x.left = put(x.left, key, val);
    else if (cmp > 0)
        x.right = put(x.right, key, val);
    else if (cmp == 0)
        x.val = val;
    return x;
}

BST的各種操作(search/insert/min/max/floor/ceiling/rank/select)用時都正比於數的高度

刪除操作程式如下,操作用時為 \(\sqrt{N}\)

public void delete(Key key){ 
    root = delete(root, key); }

private Node delete(Node x, Key key) {
    if (x == null) return null;
    int cmp = key.compareTo(x.key);
    if (cmp < 0) x.left = delete(x.left, key);
    else if (cmp > 0) x.right = delete(x.right, key);
    else {
        if (x.right == null) return x.left;
        if (x.left == null) return x.right;

        Node t = x;
        x = min(t.right);
        x.right = deleteMin(t.right);
        x.left = t.left;
    }
    x.count = size(x.left) + size(x.right) + 1;
    return x;
}