Download presentation
Presentation is loading. Please wait.
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)
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.