Presentation is loading. Please wait.

Presentation is loading. Please wait.

Data Structures Dynamic Sets Heaps Binary Trees & Sorting Hashing.

Similar presentations


Presentation on theme: "Data Structures Dynamic Sets Heaps Binary Trees & Sorting Hashing."— Presentation transcript:

1 Data Structures Dynamic Sets Heaps Binary Trees & Sorting Hashing

2 Dynamic Sets Data structures that hold elements indexed with (usually unique) keys Support of some basic operations such as:  Search for an element with a given key  Insert a new element  Delete an element  Find the minimum-key element  Find the maximum-key element Elements can have unique or non-unique keys, depending on the application Keys can be ordered (e.g., intergers)

3 Some operations on dynamic sets SEARCH(S, k) Given set S, key k, return x such that key(x) = k, or NIL if not found INSERT(S, x) Augment S by adding x to it DELETE(S, x) Delete x from S MINIMUM(S), MAXIMUM(S) Return element x in S with minimum (maximum) key(x) SUCCESSOR(S, x) Given x, return y in S with minimum key(y) > key(x), or NIL if key(x) is maximum PREDECESSOR(S, x)

4 Data Structures for Sets Several data structures can support sets  Arrays  Linked Lists  Trees  Heaps  Hash Tables  etc… Depending on the required set of operations, and on their frequency, different data structures are preferable

5 Example: Linked Lists A list L consists of a head, head[L], and a set of values Every list ends with NIL Lists can additionally point to objects indexed by the keys 91641NIL head[L] 9 1641NIL

6 Variants of Linked Lists Simple Doubly linked Circular  Notice the sentinel NIL 91641NIL head[L] NIL head[L] 9164NIL1 nil[L] 1641

7 Implementing Sets as Lists HEAD(L)return nil[L].next TAIL(L)return nil[L].prev INSERT(L, x) x.next = HEAD(L) HEAD(L).prev = x HEAD(L) = x x.prev = nil[L] nil[L] 41 111 x

8 Implementing Sets as Lists HEAD(L)return nil[L].next TAIL(L)return nil[L].prev INSERT(L, x) x.next = HEAD(L) HEAD(L).prev = x HEAD(L) = x x.prev = nil[L] nil[L] 41 111 x

9 Implementing Sets as Lists HEAD(L)return nil[L].next TAIL(L)return nil[L].prev INSERT(L, x) x.next = HEAD(L) HEAD(L).prev = x HEAD(L) = x x.prev = nil[L] nil[L] 41 111 x

10 Implementing Sets as Lists HEAD(L)return nil[L].next TAIL(L)return nil[L].prev INSERT(L, x) x.next = HEAD(L) HEAD(L).prev = x HEAD(L) = x x.prev = nil[L] nil[L] 41 111 x

11 Implementing Sets as Lists HEAD(L)return nil[L].next TAIL(L)return nil[L].prev INSERT(L, x) x.next = HEAD(L) HEAD(L).prev = x HEAD(L) = x x.prev = nil[L] nil[L] 41 111 x

12 Implementing Sets as Lists LIST-DELETE(L, x) x.prev.next = x.next x.next.prev = x.prev LIST-SEARCH(L, k) x = HEAD(L) while x != nil(L) and x.key != k x = x.next return x How fast do INSERT and DELETE run? How fast does LIST-SEARCH run? 1641

13 Sorted Lists INSERT x  Search for y such that y.key ≤ x.key ≤ y.next.key DELETE x  Same as unsorted lists MINIMUM  Return HEAD(L) MAXIMUM  Return TAIL(L) LIST-SEARCH x  Same as unsorted lists EXTRACT-MAX  DELETE MAXIMUM

14 Running Times of Basic Operations UNSORTED LISTSORTED LIST INSERT constantO(N) DELETE constant SEARCH O(N) MINIMUM O(N)constant MAXIMUM O(N)constant EXTRACT-MAX O(N)constant

15 Heaps Heap: a very efficient binary tree data structure Heap operations  INSERT  DELETE  EXTRACT-MAX Heapsort A priority queue based on heaps  Heap operations  DECREASE-KEY

16 Heaps: Definition A heap is an array A[1,…,length(A)] heap_size(A) ≤ length(A), is the size of the heap A[1], …, A[heap_size(A)] are elements in the heap 1614791083241 A Contents of the heap heap_size(A) length(A)

17 Heaps: Definition A heap is also a binary tree PARENT(i) return  i/2  LEFT(i) return 2i RIGHT(i) return 2i+1 1614791083241 A 16 14 79 10 83 241

18 Heaps: Definition The heap property: For every i > 1, A[PARENT(i)] >= A[i] 1614791083241 A 16 14 79 10 83 241

19 Maintaining the Heap Property Example: Heap property is violated at root Left and right trees are heaps HEAPIFY(A,1) will fix this 4167910143281 A 4 16 79 10 143 281

20 Maintaining the Heap Property HEAPIFY Propagate the problem down 1647910143281 A 16 4 79 10 143 281

21 Maintaining the Heap Property HEAPIFY Propagate the problem down At each step, replace problem node with largest child 1614791043281 A 16 14 79 10 43 281

22 Maintaining the Heap Property HEAPIFY Propagate the problem down At each step, replace problem node with largest child 1614791083241 A 16 14 79 10 83 241

23 Maintaining the Heap Property HEAPIFY(A, i) l = LEFT(i) r = RIGHT(i) if l A[i] then max = l else max = i if r A[max] then max = r if max != i then exchange(A[i], A[max]) HEAPIFY(A, max) 4167910143281 A 4 16 79 10 143 281

24 Heaps are balanced Claim: The size of each child heap is < 2/3 N, where N is the size of the parent Proof: Let N: parent heap size A, B: child heap sizes Worst case: a = 2 k, b= 0 B = 1 + … + 2 k-1 = 2 k – 1 A = 1 + … + 2 k = 2B + 1 N = 3B+2 A/N = [2(B+1) – 1] / [3(B+1) – 1] < 2(B+1)/3(B+1) = 2/3 N = 1 + 2 + … + 2 k + a + b = A + B A = 1 +…+ 2 k-1 + aB = 1 +…+ 2 k-1 + b ab k

25 HEAPIFY runs in time O(log n) T(n) < T(2/3 n) +  (1) =  (log n) by the Master Theorem [[ Case 2: T(n) = 1 T(n/ (3/2) ) + c f(n) = c; a = 1; b = 3/2; n log b a = n log 3/2 1 = n 0 = 1 f(n) =  (n log b a ) therefore T(n) =  (n log b a log n) =  (log n) ]] Alternatively, T(n) = O(h), where h is height of the heap

26 Building a Heap 4116932101487 A 4 1 169 3 210 1487 Build a heap starting from an unordered array

27 Building a Heap 4116932101487 A 4 1 169 3 210 1487 The leafs are already heaps of size 1

28 Building a Heap 4116932101487 A 4 1 169 3 210 1487 Go up one-by-one to the root, fixing the heap property

29 Building a Heap 4116931410287 A 4 1 169 3 1410 287 Go up one-by-one to the root, fixing the heap property Do that by running HEAPIFY

30 Building a Heap 4116910143287 A 4 1 169 10 143 287 Go up one-by-one to the root, fixing the heap property Do that by running HEAPIFY

31 Building a Heap 4167910143281 A 4 16 79 10 143 281 Each HEAPIFY takes time O(height)

32 Building a Heap 1614791083241 A 16 14 79 10 83 241 Each HEAPIFY takes time O(height)

33 Building a Heap 1614791083241 A 16 14 79 10 83 241 BUILD-HEAP(A) heap_size[A]= length(A) For i =  length(A)/2  downto 1 HEAPIFY(A, i)

34 Running Time of BUILD-HEAP How fast does BUILD-HEAP run??? Here is a bound:  At most N = heap_size(A) calls to HEAPIFY  Each call takes at most O(log N) time  Therefore, running time is O(N log N) Are we done?

35 Two lemmas left as exercises Lemma 1  An N-element heap has height  lg N  Lemma 2  An N-element heap has at most  N / 2 h+1  nodes of height h 16 14 79 10 83 241 height h = 3 3 2 1 0

36 Running Time of BUILD-HEAP Each HEAPIFY takes time O(h) HEAPIFY is called at most once/node T(N) =  h = 0…  lg N   N / 2 h+1  O(h) ≤ O(N  h = 0…  lg N  h/2 h )  h = 0…  lg N  h/2 h <  h = 0…  [ h×(1/2) h ] = (1/2)/(1-1/2) 2 = 2, by [A.8] = O(2N) = O(N) !

37 Heapsort 1614791083241 A 16 14 79 10 83 241 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 16 1 1 1

38 Heapsort 1614791083241 A 16 14 79 10 83 241 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 16 1 1 1

39 Heapsort 1614791083241 A 16 14 79 10 83 241 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 16 1 1 1

40 Heapsort 148791043211 A 8 79 43 211 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 1 16 14

41 Heapsort 187910432141 A 8 79 10 43 2141 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 1 16 1

42 Heapsort 187910432141 A 8 79 10 43 2141 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 1 16 1

43 Heapsort 108719432141 A 8 71 9 43 2 1 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 1 16 10

44 Heapsort 287194310141 A 8 71 9 43 10141 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 1 16 2

45 Heapsort 287194310141 A 8 71 9 43 10141 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 1 16 2

46 Heapsort 987134210141 A 8 71 3 42 10141 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 1 16 9

47 Heapsort 872134910141 A 7 21 3 49 10141 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 1 16 8

48 Heapsort 742831910141 A 4 28 3 19 10141 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 1 16 7

49 Heapsort 427831910141 A 4 78 3 19 10141 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 1 16 7

50 Heapsort 327814910141 A 2 78 1 49 10141 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 1 16 3

51 Heapsort 217834910141 A 1 78 3 49 10141 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 1 16 2

52 Heapsort 127834910141 A 2 78 3 49 10141 HEAPSORT(A) BUILD-HEAP(A) for I = length(A) downto 2 exchange(A[1], A[i]) heap_size(A)-- HEAPIFY(A, 1) 1 1 16 1 RUNNING TIME?

53 Priority Queues A priority queue S is a data structure supporting: MAXIMUM(S)  Returns maximum key in S EXTRACT-MAX(S)  Removes maximum key in S, and returns it INCREASE-KEY(S, x ptr, x new )  Increases x old, stored in x ptr, into x new > x old INSERT(S, x)  S = S  {x} PRIORITY QUEUE

54 Heaps as Priority Queues Heaps can be efficient priority queues  MAXIMUM is implemented in O(1) MAXIMUM(A) return A[1]  EXTRACT-MAX is implemented in?? EXTRACT-MAX(A) if heap_size(A) < 1 then error(“underflow”) max = A[1] A[1] = A[heap_size(A)] heap_size(A)-- HEAPIFY(A, 1) return max

55 Heaps as Priority Queues  INCREASE-KEY is implemented in O(log n) INCREASE-KEY(A, i, key) if key < A[i]then error(“key too small”) A[i] = key while i>1 && A[PARENT(i) < A[i]] exchange(A[i], A[PARENT(i)] i = PARENT(i)

56 Example of INCREASE-KEY 1614791083241 A 16 14 79 10 83 241 INCREASE-KEY(A, i, key) if key < A[i] then error(“key too small”) A[i] = key while i > 1 and A[PARENT(i)] < A[i] exchange (A[i], A[PARENT(i)]) i = PARENT(i)

57 Example of INCREASE-KEY 16147910832151 A 16 14 79 10 83 2151 INCREASE-KEY(A, i, key) if key < A[i] then error(“key too small”) A[i] = key while i > 1 and A[PARENT(i)] < A[i] exchange (A[i], A[PARENT(i)]) i = PARENT(i)

58 Example of INCREASE-KEY 16147910153281 A 16 14 79 10 153 281 INCREASE-KEY(A, i, key) if key < A[i] then error(“key too small”) A[i] = key while i > 1 and A[PARENT(i)] < A[i] exchange (A[i], A[PARENT(i)]) i = PARENT(i)

59 Example of INCREASE-KEY 16157910143281 A 16 15 79 10 143 281 INCREASE-KEY(A, i, key) if key < A[i] then error(“key too small”) A[i] = key while i > 1 and A[PARENT(i)] < A[i] exchange (A[i], A[PARENT(i)]) i = PARENT(i)

60 Example of INCREASE-KEY 16157910143281 A 16 15 79 10 143 281 INCREASE-KEY(A, i, key) if key < A[i] then error(“key too small”) A[i] = key while i > 1 and A[PARENT(i)] < A[i] exchange (A[i], A[PARENT(i)]) i = PARENT(i)

61 Heaps as Priority Queues  INSERT is implemented in O(log n) INSERT(A, key) Heap_size(A)++ A[heap_size(A)] = -Infinity INCREASE-KEY(A, heap_size(A), key) 16 15 79 10 143 281 16 15 79 10 143 281 11 INSERT 11 -- 16 15 119 10 143 281 7

62 Summary UNSORTED LISTSORTED LISTHEAP INSERT cO(N)O(log N) DELETE ccO(log N) SEARCH O(N) MAXIMUM O(N)cc EXTRACT-MAX O(N)cO(log N) INCREASE-KEY cO(N)O(log N)


Download ppt "Data Structures Dynamic Sets Heaps Binary Trees & Sorting Hashing."

Similar presentations


Ads by Google