1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue...

112
1 Chapter 13 Priority Queues

Transcript of 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue...

Page 1: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

1

Chapter 13

Priority Queues

Page 2: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

2

Chap.13 Contents

13.1 Introduction13.2 The PurePriorityQueue Interface

13.3 Implementations of the PurePriorityQueue Interface 13.3.2 The Heap Implementation of the PurePriorityQueue Interface

13.4 Application: Huffman Codes

Page 3: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

3

13.1 Introduction

A priority queue (PQ) is an interface (property) in which access or deletion is of:

the highest-priority element,

according to some method of

assigning priorities to elements.

Page 4: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

4

舉個例子, 假設 hospital emergency room (急診室) 有四個病患, 並有下列三種資料:

姓名, 受傷程度, 傷勢

Page 5: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

5

姓名 受傷程度 傷勢

張三 80 足踝扭傷 李四 45 腿斷了 王五 80 足踝扭傷 林二 20 頭部中彈 四位病患該以怎樣的順序來排隊看診?

Page 6: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

6

規則為: 受傷程度最小值 表示最嚴重 有 最高優先權 (highest priority). 所以,急診室前排了 priority queue 如下:

20(林二) 45(李四) 80(張三)80(王五) 可用下面 interface來實作優先權的比較: 1) The comparable interface or

2) The comparator interface.

急診室

Page 7: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

7

13.2 The PurePriorityQueue Interface

public interface PriorityQueue {

/*** size 回傳 PurePriorityQueue 中元素的個數*/int size ( )

Page 8: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

8

/* isEmpty 看 PurePriorityQueue * 是否沒有元素 .

** return true – if PurePriorityQueue* 沒有元素 ;* otherwise, return false ;*/boolean isEmpty ( )

Page 9: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

9

/*** add 加元素到 PurePriorityQueue .** The worstTime(n) is O(n).** @param element – 要插入 PurePriorityQueue 的元素*/void add (E element)

Page 10: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

10

/* getMin * 回傳 PurePriorityQueue 中的最高優先權元素 *

* The worstTime(n) is O (1).** @return PurePriorityQueue 的最高優先權元素** @throws NoSuchElementException – * if PurePriorityQueue 是空的*/E getMin ( )

Page 11: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

11

/* removeMin* 從 PurePriorityQueue 移除具有最高優先權的元素

** The worstTime(n) is O (log n).** @return 被移除的元素**@throws NoSuchElementException – * if PurePriorityQueue 是空的*/E removeMin ( )

Page 12: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

12

13.3 Implementations of The PurePriorityQueue Interface

有三種 data structures 可實作之,分別是 :

1) linked list

2) tree set

3) heap

Page 13: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

1. Use Linked List

13

Page 14: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

14

public class LinkedPQ <E> impelments

PurePriorityQueue <E> {

LinkedList <E> list ;

Comparator <E> comparator ;

Page 15: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

15

public LinkedPQ()

{list = new LinkedList<E>( ) ;

comparator = null ; }

public LinkedPQ (Comparator<E> comp)

{this() ; comparator = comp ;}

public int size() { return list.size() ; }

public E getMin() { return list.getFirst() ; }

public E removeMin(){ return list.removeFirst() ;}

Page 16: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

16

下頁 add(): 假設有個 element 優先權為 22, 並有個 linked list 實作的 priority queue 如下:

10, 12, 18, 25, 39 當 element < itr.next( ), loop 會終止,

也就是說,,當 22 < 25 會離開 loop 但因為 itr 目前指到 39之前 25之後 所以須 將 itr 倒退一位到 25之前 18之後. add 22 即可加到 18 與 25之間

Page 17: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

17

public void add (E element){

if /* 空或 element優先權比最後的大 */

(list.isEmpty( ) || compare (element, list.get (list.size( ) – 1)) >= 0)

/* 直接 add此 element*/ list.add (element) ;

else {/*找適當位置 add 使優先權由小到大 */ ListIterator<E> itr = list.listIterator( );

while (itr.hasNext() && compare (element, itr.next( )) >= 0) ;

/*倒退一位 , 再 add*/ itr.previous( ) ; itr.add (element) ;

}} //end of add

WorstTime (n) is linear in n.

Page 18: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

18

protected int compare (Object elem1, Object elem2) { /*IF comparator = null,

回傳 elem1.compareTo (elem2)的結果。 OTHERWISE, 回傳 comparator.compare (elem1, elem2) 的結果。*/

return (comparator==null ? ((Comparable)elem1).compareTo(elem2)

: comparator.compare (elem1, elem2)); } // end of compare

Page 19: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

19

2. Use Tree Set

Page 20: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

20

public class TreeSetPQ<E> implements PriorityQueue<E> {

TreeSet<E> set;

Comparator<E> comparator;

// the 2 constructors, size, isEmpty and compare

// methods 與 LinkedPQ class 的類似

public TreeSetPQ (Comparator<E> c) {

comparator = c ; set = new TreeSet<E> (c);

} // one-parameter constructor

Page 21: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

21

public void add (E element) {set.add (element);}

public E getMin ( ) {return set.first( );}

public E removeMin ( ) {E temp = set.first( ); set.remove (set.first( )); return temp;}

} // end of class TreeSetPQ

For these three methods, worst time (n) is logarithmic in n.

Page 22: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

3. Use Heap

22

Page 23: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

23

現在來看完全不一樣的!

public class Heap implements PriorityQueue {

尚未納入 Java collections framework

什麼是 Heap?

Page 24: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

24

Heap [Collins English Dictionary]

A collection of articles or mass of material gathered together in one place. 這定義用於 compiler, OS.Ex: Heap storage (堆 ) vs. stack storage ( 疊 ) in main

memory.

Page 25: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

25

但是, Data Structure 中的 Heap , 有不同的定義 :

Heap 是一棵 tree , 且任何一個節點比 所有 descendants ( 後代 ) 都小

Page 26: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

26

Recall that: A complete binary tree is full Except at the lowest level,

where all items are as far to the left as possible.

Page 27: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

27

heap t 是 complete binary tree , 且 t是空的 或 :

1. root element是 t中最小元素 2. t 的左右子樹 (sub-tree) 都是 heap.

Page 28: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

28

26 index 0

40 31 index 2 48 50 85 index 5 36 107 48 55 57 88 index 11

Page 29: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

29

heap 不是 binary search tree!

因為對 root 而言binary search tree 是 左小右大

heap 則是上 (root)小 下 ( 左右 ) 大 這叫 min heap (minimal element at root)

另有 max heap (maximal element at root)

則是下 ( 左右 ) 小 上 (root) 大

Page 30: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

30

跟 complete binary tree一樣, Heap可以 Array方式儲存:

root element 為 index 0, root element 的 left child 為 index 1, 以此類推:

index 0 1 2 3 4 5 6 7 8 9 10 11

26 40 31 48 50 85 36 107 48 55 57 88

Page 31: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

31

如同我們在 Chapter 9看到的,

當 complete binary tree 被儲存成 array時,

從 parent index 走到 child index 以及 從 child index 走到 parent index的

執行時間是 constant-time

Page 32: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

32

下列的學生分數程式,創出 Heap 結構 ,並執行 Heap 動作 : add 和 removeMin

請輸入學生姓名及 GPA 或 ***( 結束 )”;

Mary 4.0 (red indicates user input)

John 3.5

***

系統輸出如下John 3.5

Mary 4.0

Page 33: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

33

public static void main(String[] args){ final String PROMPT= “ 請輸入學生姓名及 GPA 或 ***( 結束 )”; final String RESULTS =“\n 學生姓名及 GPA 如下” ; String line ;

Heap<Student> heap = new Heap<Student>( ) ; BufferedReader keyboardReader = new BufferedReader (new InputStreamReader(System.in) ) ; try{ while(true) {System.out.print (PROMPT) ;

line = keyboardReader.readLine() ; if (line.equals(“***”)) break ;

heap.add (new Student(line) );} //while

system.out.println (RESULTS); while(!heap.isEmpty()) System.out.println (heap.removeMin() ) ;

}//try catch(Exception e){ System.out.println(e) ;}} // end of main

Page 34: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

34

import java.util.* ;

public class Student implements Comparable { protected String name ; protected double gpa ;

/** Student 從特定的 String s 初始化 Student object.** @param s – String 初始化 Student object.*@throws NullPointerException, NoSuchElementException,* NumberFormatException*/

public Student (String s){StringTokenizer tokens = new StringTokenizer(s) ;name = tokens.nextToken() ;gpa = Double.parseDouble( tokens.nextToken() ) ;

} // constructor

public String toString() {return name+“ “+ gpa;}

} // end of class Student

Page 35: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

35

Data Structure in the heap class:

protected E[ ] heap; protected int size; protected Comparator<E> comparator;

13.3.2 The Heap Implementation of the PurePriorityQueue Interface

Page 36: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

36

heap [j]

heap [2 * j + 1] heap [2 * j + 2]

Page 37: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

37

heap [(j – 1) / 2]

heap [j] heap [j + 1]

Page 38: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

38

Implementation of the heap class

public Heap( ) { final int DEFAULT_INITIAL_CAPACITY = 11; heap = (E[ ]) new Object [DEFAULT_INITIAL_CAPACITY]; } // default constructor

Page 39: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

39

// add an element to the heap // Postcondition: element 加入 heap // worstTime (n) is O(n), // averageTime (n) is constant. public void add (E element) { /* 1.假設 heap 現有三元素(size為 3) 容量(length)為 10 size先加 1 (為 4) 未達 10 故不 resize(容量加倍)*/ if (++size == heap.length) /* then resize */ { E[ ] newHeap = (E[]) new Object [2 * heap.length]; System.arraycopy (heap, 0, newHeap, 0, size); heap = newHeap ; } // end if /* 2.heap 現有三元素的 array index為 0,1,2 下一元素放最後 即 index為 3 即 size (4) 減 1*/

heap [size - 1] = element;

/* 3. 最後元素向上滲透*/ percolateUp ( ); } // end of add

Page 40: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

40

加入 30 到下列的 Heap: 26

32 31 48 50 85 36 107

Page 41: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

41

26

32 31 48 50 85 36 107 30 percolateUp( ): 30 藉 swapping往上滲透 , 直到調整成 Heap結構

Page 42: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

42

26

32 31 30 50 85 36 107 48

Page 43: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

43

26 30 31 32 50 85 36 107 48

Page 44: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

44

Protected void percolateUp(){ // 設定 child 為 最後一個 node (size -1) int child = size -1; int parent; Object temp ;

while(child > 0){ parent = (child-1)/2; // 如果 parent <= child 不用做了 if(compare(heap[parent],heap[child] <= 0) break;

// 否則 swap parent 與 child temp=heap[parent];heap[parent]=heap[child];heap[child]=temp; /*child 向上走一步 */ child = parent; }//end while} //end of percolateUp

Page 45: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

45

// Precondition: Heap不為空 // Otherwise, 拋出 NoSuchElementException // Postcondition: 刪除 Heap最高優先權元素,並回傳之 // // The worstTime(n) is O(log n). public E removeMin ( ) { if (size==0) throw new NoSuchElementException ("Priority queue empty.");

/*1.假設 heap有三元素其 index 0 1 2, size 為 3 index 0 為 minimal element*/E minElem=heap[0]; /*2.移最後元素(index 2, 即 size 減 1)到 index 0 heap [0] = heap [size–1]; /*3. size 少 1 變成 2*/ size--;

/* 4 index 0元素向下滲透*/ percolateDown (0); /* 5*/ return minElem; } // end of removeMin

Page 46: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

46

26 30 31 32 50 85 36 107 48 當 removemin( ) 被呼叫, 48 會與 26 交換,並將 size 從 9變小為 8。

Page 47: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

47

48 30 31 32 50 85 36 107 percolateDown (0): 48 (at index 0) 持續與 children swapping向下滲透,直到調整成 heap結構。

Page 48: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

48

30 48 31 32 50 85 36 107

Page 49: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

49

30 32 31 48 50 85 36 107

Page 50: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

50

Protected void percolateDown(int start){ // parent 為 tree 的 root (index 0 ) // child 為 root 的左子樹 int parent = start, child = 2*parent + 1; Object temp ; while(child < size){

// 如 child 有右兄弟 且 右兄弟較小 則設定 child 為右兄弟 if(child < size – 1 && compare(heap[child],heap[child+1])> 0) child ++;

// 如 parent <= child 不用再比了

if(compare(heap[parent],heap[child] <= 0) break;// 否則 swap parent 與 child

temp = heap[child]; heap[child] = heap[parent];heap[parent] = temp;

// child 向下走一步 parent = child; child = 2 * parent +1; }//while} // end of percolateDown

Page 51: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

51

Exercise: 畫出最後的 Heap結構 Heap<Integer> myHeap = new Heap<Integer>( ); myHeap.add (new Integer (60)); myHeap.add (new Integer (50)); myHeap.add (new Integer (40)); myHeap.add (new Integer (30)); myHeap.add (new Integer (20)); myHeap.add (new Integer (10)); myHeap.removeMin( ); myHeap.removeMin( ); myHeap.removeMin( );

Page 52: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

52

40

60 50

實際儲存於 array: 40 60 50 index: 0 1 2

Page 53: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

53

13.4 Application: Huffman Codes

問題: 如何 encode message 使之為最節省空間的 code (用 bit表示), 傳輸 code 至遠端後, 遠端可 decode code還原為 message

Page 54: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

54

例子: m (message) 為 100,000 個下面字母組成:

‘a’, b’, ‘c’, ‘d’, ‘e’.

encode(編碼) m 成 bit組成的 code叫 e

Page 55: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

55

在 Java unicode編碼中, 每個字母編成 16 bits. 如採用此,

|e| 表示 e的 size 為:

1,600,000 bits

Page 56: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

56

假設每一字母都使用固定數目的 bits 最少需要多少 bits,才能將 5個字母編碼,而且是唯一編碼?

Page 57: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

57

若每個字母所表示的 bits數目相同 將 5個字母編碼成唯一編碼, 則每個字母需要

3 bits

Page 58: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

58

將 n個字母編碼成唯一編碼 需要最少 bits數為:

the number of bits in the binary representation of n:

ceil (log2 n)

ceil(x): 大於或等於 x的最小整數

Page 59: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

59

這是可能的編碼:

‘a’ 000 ‘b’ 001 ‘c’ 010 ‘d’ 011 ‘e’ 100

Page 60: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

60

|e| = 100000 * 3 =

300,000 bits

Page 61: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

61

可以更好一點嗎? 可以! 希望 n個字母的編碼中, 不需每個字母都要 ceil (log2 n)個 bits 就像這樣子:

‘a’ 0 ‘b’ 1 ‘c’ 00 ‘d’ 01 ‘e’ 10

Page 62: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

62

|e| << 300,000 bits

可是…

Page 63: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

63

有矛盾的狀況產生: 001010 解碼 (decode) 成:

adda or cee or …

Page 64: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

64

產生上述矛盾, 是因為有些字的編碼 是其他字編碼的 Prefix 例如 :

a 0 c 00

(a是 c 的 prefix)

Page 65: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

65

採用 prefix-free (無 prefix) 的編碼方式才會

沒有矛盾狀況 (unambiguous)

Page 66: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

66

要得到 prefix-free encoding, 必須創造 binary tree:

左邊分支(branch) 表示 0 bit 右邊分支(branch) 表示 1 bit

而每個字母位在 leaf

Page 67: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

67

0 1

0 1 0 1 c d b 0 1

a e

Page 68: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

68

因為每個字母都是 leaf, 各字母從 root到 leaf不會走同樣路徑 這實現了 prefix-free (unambiguous) 編碼 如: ‘a’ 010 ‘b’ 11 ‘c’ 00 ‘d’ 10 ‘e’ 011

Page 69: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

69

這是另一棵 unambiguous 編碼的 binary tree:

0 1 0 1 b c 0 1 a 0 1 e d

Page 70: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

70

要決定 |e|, 我們必須知道:

在 message中, 各字母的 frequency.

Page 71: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

71

Huffman Tree 是根據: message(m)中字母的 frequency 創 minimal prefix-free encoding 的 binary tree

Page 72: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

72

將出現頻率最少 (least-frequently) 的字母, 放在離 root最遠的 leaf 使它的編碼會有最多 bits 例如, “a” 編碼成 “1100” 有 4 bits.

Page 73: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

73

假設 frequencies 如下:

‘a’ 5,000 ‘b’ 20,000 ‘c’ 8,000 ‘d’ 40,000 ‘e’ 27,000

left-branch for least(最小) right-branch for next-to-least(次小)

Page 74: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

74

0 1

a c

Page 75: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

75

0 1 a c 結果如何? 總共的 frequencies 是 13,000. 比 b的 frequency (20,000) 少, 所以我們創造上層 2分支 (branches):

這棵 subtree 會是左分支, 而 b 會是右分支 (見下頁)

Page 76: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

76

0 1 b 0 1 a c

Page 77: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

77

這 subtree的 frequencies 是 33000 (次小)

e 的 frequencies 是 27000 (最小) 所以這 subtree要成為上層右子樹,

e要成為上層左子樹 (見下頁)

Page 78: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

78

0 1

e 0 1 b 0 1

a c

Page 79: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

79

最後, 這 subtree的 frequencies 是 60000 (次小),

d的 frequencies 是 40000 (最小) 所以這 subtree要成為上層右子樹,

d成為上層左子樹

Page 80: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

80

0 1

d 0 1

e 0 1

0 1 b

a c

Page 81: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

81

‘a’ 1100 ‘b’ 111 ‘c’ 1101 ‘d’ 0 ‘e’ 10 What is the bits for the message “acceded”? What is the message for the bits “11001110101101”? See answers on next page.

Page 82: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

82

Answers: “acceded” 110011011101100100 11001110101101 -> “abdec”

Page 83: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

83

|e| =

字母的 bits數

乘以

字母的 frequnecy

Page 84: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

84

|e| = 4 * 5000 +

3 * 20000 + 4 * 8000 + 1 * 40000 + 2 * 27000

= 206,000 bits 遠小於前面提到的 1600,000 bits

及 300,000 bits

Page 85: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

85

我們用 priority queue 儲存字母的 frequencies和 subtrees add: 插入字母的 frequency 到 priority queue removeMin: 從 priority queue刪除 lowest frequency (最小)

Page 86: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

86

在 priority queue中, 每個 element由 character-frequency成對組成, 加上 left, right, parent pointers. 例如,假設 character-frequency 為:

(a: 34000) (b: 20000) (c: 31000) (d: 10000) (e: 5000)

Page 87: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

87

priority queue中 element的順序為:

e 5000 (lowest frequency) d 10000 b 20000 c 31000 a 34000

getmin( ) 回傳最高優先權 (highest-priority) 也就是 lowest-frequency的 element 即 e 5000

Page 88: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

88

removeMin被呼叫兩次: 第一個最小 element 成為 left branch,

第二個次小 element 成為 right branch, 加總其 frequencies (15000) 再加入 priority queue

( : 15000) (b: 20000) (c: 31000) (a: 34000) 所以目前的 Huffman tree 為: 15000 0 1 e d

Page 89: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

89

再一次, removeMin 又呼叫兩次, 而 frequencies的總和也被加入 PRIORITY QUEUE:

(c: 31000) (a: 34000) ( : 35000) 所以目前的 Huffman tree 為: 35000 0 1 15000 b 0 1 e d

Page 90: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

90

又一次, removeMin又呼叫兩次, 在新的 HUFFMAN TREE 中,elements 變成了 leaves ,

而 frequencies的總和也加入 PRIORITY QUEUE:

( : 35000) ( : 65000)

目前的 Huffman tree 為:

35000 0 1 15000 b 65000 0 1 0 1 e d c a

Page 91: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

91

最後,( : 35000)和 ( :65000) 也從 priority queue移除, 並將總和加入 priority queue,, 目前 priority queue 為:

( : 100000).

最後的Huffman tree 為:

Page 92: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

92

100000 0 1

35000 0 1

15000 b 65000

0 1 0 1

e d c a

Page 93: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

93

Exercise: create a minimal, prefix-free encoding for the following character-frequency pairs: ‘a’ 20,000 ‘b’ 4,000 ‘c’ 1,000 ‘d’ 17,000 ‘e’ 25,000 ‘f’ 2,000 ‘g’ 3,000 ‘h’ 28,000 Note: you will need to maintain the priority queue, ordered by frequencies.

Page 94: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

94

13.4.3 The Huffman Encoding Project

重複以下動作: 從 priority queue中, 移除兩個最小 frequency的元素, 然後創造 huffman tree的 subtree,

最後將得到 minimal (prefix-free) encoding.

Page 95: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

95

Huffman Class 會:

encode message 成為 code

首先看看 Entry Class:

Page 96: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

96

class Entry implements Comparable { int freq; // ex 31000 String code;// ex 10 ENCODING char id; // ex c

Entry left, //ex null right, //ex null BINARY TREE parent;// node (entry) with freq. 65000 public int compareTo (Object entry) {return freq - ((Entry)entry).freq; } } // class Entry

Page 97: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

97

protected Entry [ ] leafEntries; ARRAY INDEX = ASCII FOR CHARACTER ‘A’ 65 That is, (int)’A’ = 65 ‘0’ 48 (int)’0’ = 48

Page 98: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

98

例如, 因為 (int)’c’ = 99, leafEntries array其中的一個 entry如下

leafEntries [99] 31000 10 c

65000 65000

null null

Page 99: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

99

Huffman Class的 Method interfaces :

Page 100: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

100

// Postcondition: 這個 Huffman object 已初始 public Huffman( ); // Postcondition: The file name in the input line s has // been processed. public void processInput (String s); // Postcondition: 從輸入資料創出 priority queue 叫 pq // The worstTime(n) is O(n). public void createPQ( ) throws IOException;

Page 101: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

101

// Postcondition: 創出 Huffman tree // The worstTime(n) is constant. public void createHuffmanTree( ); // Postcondition: 計算過 Huffman codes The worstTime(n) is constant. public void calculateHuffmanCodes( ); // Postcondition: Huffman codes和編碼後訊息存檔 // The worstTime (n) is O (n). public void saveToFile() throws IOException;

Page 102: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

102

Huffman Class中的 Data Structure: 除了 1) leafEntries, 還需要: 2) a graphical user interface (gui) and

3) a priority queue (pq). 還有, 4) a file reader, 5) a file writer, 和 6) a boolean variable 來判斷

哪一個檔案名稱被讀取.

Page 103: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

103

最後, 儲存 7) the input file name 我們開啟 input file兩次: 一次 計算 frequencies 另一次 編碼 message

Page 104: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

104

// Data structure

protected Entry [ ] /*1*/ leafEntries; protected GUI /*2*/ gui; protected PriorityQueue /*3*/ pq; protected BufferedReader /*4*/ fileReader; protected PrintWriter /*5*/ fileWriter; protected boolean /*6*/ readingInFileName; protected String /*7*/ inFileName;

Page 105: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

105

這是 4 個 Huffman class methods的 high-level pseudocodes : 跟預期一樣 processinput 是 high-level controller: 它創造了: 1) the priority queue (pq) and

2) the Huffman tree, 然後 3) calculates the Huffman codes and

4) saves the codes and encoded message

to a file.

Page 106: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

106

1) The createPq method 1. 創造 leafEntries, 每個 ASCII character都有 entry

2. 讀入每一行資料時,更新每個 character entry中的 freq field 3. 利用 frequencies 創造出 pq

Page 107: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

107

2) The createHuffmanTree method loop until pq.size( ) = 1. 1. 移除兩個 entries

變成 Huffman tree中的 左 (code = “0”) 右 (code = “1”) 分支 2. 建立新 entry,並加入到 pq,

而新 entry 的 frequency是: 被移除兩 entries 的 frequencies總和

end loop

Page 108: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

108

3) The calculateHuffmanCodes method for each entry in leafEntries whose frequency is > 0

loop until the entry has no parent 1.the entry’s code field

is prepended to (加在前面) an initially empty string variable code

2.the entry is replaced with the entry’s parent.

end loop

end for

Page 109: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

109

例如, 假設部分 Huffman tree如下( 字母 c 的 code): 1 0

c

Page 110: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

110

由下到上計算‘c’ 的 code:

0 1加在 0前面 10

因為 (int)‘c’ 為 99, “10” 儲存在 leafEntries [99] 裡的 code FIELD中 就是: c 字母的 code 是 10 兩個 bits

Page 111: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

111

最後, 4) saveToFile method 含兩部份: 1.loop through leafEntries, 將每個 character和對應的 code, 存到 output file

2. 重新讀入 input file 產生 message編碼後的 bit 組成的 code 並存到 output file

Page 112: 1 Chapter 13 Priority Queues. 2 Chap.13 Contents 13.1 Introduction 13.2 The PurePriorityQueue Interface 13.3 Implementations of the PurePriorityQueue.

112

Exercise: 下為輸出檔, 請將之解碼(decode)

11010 END OF LINE MARKER 011 BLANK . 1100 PERIOD a 11011 e 00 h 010 l 111 LOWER-CASE L s 10 ** 1001000011100011111110011100011011011100100011111110110011010

ANS: she sells sea shells.