2 AdvancedDataStructures
2 AdvancedDataStructures
CHAPTER 2
Outlines
• Binary search trees
• B-trees
• Heaps and priority queues
• Skip list
internal node
n
p q
12
10
8 17
6 19
4 9
4 9 12 20
5
6 19
4 9 12 20
6 19
4 9 12 20
leaf node
number true
of keys key1 key2 key3 keyn
leaf
11 17 68 71
6 8
12 16
75 88
26 60 69 70
66 67
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 17
Search in B-trees
B-TREE-SEARCH(x, k)
i=1
► find a proper child
while i ≤ x.n and k > x.keyi do i =i + 1
if i ≤ x.n and k = x.keyi
then return (x, i )
if x.leaf
then return NIL
► recursively search in the proper subtree
else DISK-READ (x.ci)
return B-TREE-SEARCH (x.ci, k)
8
17 26 65
26 65
11
17
11
8 11 12 16
12 16
26 65
11 17 65
6 8
12 16
26 65 65 71
71
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 22
Insertion in B-trees
66
11 17 65 71
6 8
12 16
75 88
26 60
67 71 75 88
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 23
Insertion in B-trees
70
11 17 65 71
6 8
12 16
75 88
26 60 69
66 67 68 69
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 24
Insertion in B-trees
65 70
11 17 11 17 65 7171 71
68
6 8
12 16
75 88
26 60 69
66 67
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 25
Insertion in B-trees
65
11 17 68 71
6 8
12 16
75 88
26 60 69 70
66 67
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 26
Insertion in B-trees
B-TREE-INSERT(T, k)
r = T.root
if r.n = 2t − 1
► The root node r is full, then create a new root node
then s = ALLOCATE-NODE()
T.root = s; s.leaf = FALSE
s.n = 0; s.c1 = r
► Split old root into two, and put under the new root
B-TREE-SPLIT-CHILD(s, 1, r)
B-TREE-INSERT-NONFULL(s, k)
else B-TREE-INSERT-NONFULL(r, k)
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 27
Splitting Nodes in B-trees
B-TREE-SPLIT-CHILD(x, i, y) ►Move up other 1/2 of old node
►Create a new node for j = x.n + 1 downto i + 1
z = ALLOCATE-NODE() do x.cj+1 = x.cj
z.leaf = y.leaf x.ci+1 = z
z.n = t − 1 for j = x.n downto i
►Move 1/2 of old node to new
for j = 1 to t − 1 do x.keyj+1 = x.keyj
do z.keyj = y.keyj+t x.keyi = y.keyt
if not y.leaf x.n = x.n + 1
then for j = 1 to t DISK-WRITE(y)
do z.cj = y.cj+t DISK-WRITE(z)
y.n = t − 1 DISK-WRITE(x)
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 28
Binary Heaps
Binary Heaps
• Binary heap is an array
• can be viewed as a nearly
complete binary tree
1
• each node of the tree
corresponds to an element left 2 right 3
of the array that stores the
value in the node. 4 5 6 7
1 2 3 … … n x … x
12 8
9 4 6 5 5
3 6 2 1
9 7
Min heap 11 19 20 18
15 12
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 33
Heapify
12 8
9 4 6 5
3 6 2 1
12
7
12
7 8
9 4 6 5
3 6 2 1
12
7
9 8
7
9 4 6 5
3 6 2 1
2
11 3
7
4
9 11
10
52 6 7
3
8 9
4 10
2 11
5
1
11
11
10
1 7
9 10
5
1 6 3
8 4 2 5
1
2 3
4 5 6 7
8 9 10 11
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 41
Time to Build Max-heaps
Let n be the heap size,
T(n) be the time spent in BUILD-MAX-HEAP for heap of size n,
t(h) be the time spent in MAX-HEAPIFY for the heap of height h,
k(h, n) be the number of subtrees of height h in the heap of size n.
lg n lg n lg n
T(n) t(h) k(h, n) = c h n/2h+1 = c n (h/2h)
h=0 h=0 2 h=0
lg n
T(n) = O(n (h/2h))
h=0
Since (h/2h)) = 2, T(n) = O(n).
h=0
HEAP-MAXIMUM(A)
return A[1]
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 46
Extract-Max In Priority Queues
HEAP-EXTRACT-MAX(A)
if heap-size[A] < 1
then error “heap underflow”
► Take the maximum element from the root
max = A[1]
► Move the last element in the heap to the root
A[1] = A[heap-size[A]]
heap-size[A] = heap-size[A] − 1
► Heapify
MAX-HEAPIFY(A, 1)
return max
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 47
Increase Key
HEAP-INCREASE-KEY(A, i, key)
if key < A[i ]
then error “new key < current key”
A[i ] = key
► Swap the increased element with its parent up toward
► the root until it is not greater than its parent
while i > 1 and A[PARENT(i)] < A[i ]
do exchange A[i] and A[PARENT(i)]
i = PARENT(i)
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 48
Insert
MAX-HEAP-INSERT(A, key)
► Insert the minimum element
heap-size[A] = heap-size[A] + 1
A[heap-size[A]]=−∞
► Increase the minimum element
HEAP-INCREASE-KEY(A, heap-size[A], key)
level
From: Cormen, T., C. Leiserson, R. Rivest, and C. Stein, Introduction to Algorithms, MIT Press, 2001.
head[H] 10 1 6
B0 12 25 8 14 29
18 11 17 38
B2 27
B3
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 56
Nodes in Binomial Heaps
parent
key
degree
child sibling
18 11 17 38 8 14
2 1
27
11 17 38
1 0 0
\ \ \ \
head
x = H.head 10 1 6
min = ∞
while x NIL 12 25 8 14 29
do if x.key < min
then min = x.key 18 11 17 38
y=x
x = x.sibling 27
return y
Maximum number of trees = lg n + 1,
the running time of BINOMIAL-HEAP-MINIMUM = O(lg n)
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 59
Link Binomial Heaps
• Make node y the new B2 8 B2 6
head of the linked list of
11 17 14 29
node z’s children in O(1)
time.
BINOMIAL-LINK(y, z) 27 y 38 z
y.p = z
y.sibling = z.child B3
z.child = y
z.degree = z.degree + 1
From: Cormen, T., C. Leiserson, R. Rivest, and C. Stein, Introduction to Algorithms, MIT Press, 2001.
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 62
Union Binomial Heaps: case 2
• x.degree = next-x.degree = next-x.sibling.degree
• move up to the next tree (and they will be linked in
next step)
From: Cormen, T., C. Leiserson, R. Rivest, and C. Stein, Introduction to Algorithms, MIT Press, 2001.
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 63
Union Binomial Heaps: case 3
x.key next-x.key
x.key<next-x.key
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 64
Binomial-Heap-Union
BINOMIAL-HEAP-UNION(H1, H2) ► Cases 1 and 2
H = MAKE-BINOMIAL-HEAP() then prev-x = x
H.head = x = next-x
BINOMIAL-HEAP-MERGE(H1, H2) else if x.key ≤ next-x.key
► Case 3
Free the objects H1 and H2 but not then x.sibling = next-x.sibling
the lists they point to BINOMIAL-LINK(next-x, x)
► Case 4
if H.head = NIL else if prev-x = NIL
then return H then H.head = next-x
prev-x = NIL else prev-x.sibling = next-x
x = H.head BINOMIAL-LINK(x,next-x)
next-x = x.sibling x = next-x
while next-x NIL next-x = sibling[x]
do if (x.degree next-x.degree) or return H
(next-x.sibling NIL and
next-x.sibling.degree=x.degree)
From: Cormen, T., C. Leiserson, R. Rivest, and C. Stein, Introduction to Algorithms, MIT Press, 2001.
parent
key
degree
mark
left right
child
From: Cormen, T., C. Leiserson, R. Rivest, and C. Stein, Introduction to Algorithms, MIT Press, 2001.
4 7 nil
2 6 11
9 12
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 79
Skip List v.s. Binary search tree
4 7 nil
2 6 11
9 12
4 11
2 6 9 12
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 80
Search in a Skip List
Search(list, searchkey)
cn = list.head ►Start at the list head
►Start skip from top level to bottom
for i=list.level downto 1
do ► Forward until key of node exceeds search key
while ((cn.fwd[i]).key < searchkey)
do cn = cn.fwd[i]
cn = cn.fwd[1]
if cn.key = searchkey
then return(cn)
else return(null)
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 81
Search in a Skip List
H
4 7 nil
2 6 11
9 12
Search for 11
4 11
2 6 9 12
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 82
Search in a Skip List
H
4 7 nil
2 6 11
9 12
Search for 12
7
4 11
2 6 9 12
Jaruloj Chongstitvatana Chapter 2: Advanced Data Structures 83
Insert in a Skip List
Insert 5
update[3]
cn update[1]
update[2]
cn
4 7 nil
2 6 11
9 12