112
1 Chapter 13 Priority Queues

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

Embed Size (px)

Citation preview

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.