Professional Documents
Culture Documents
Rabea Aden
Friday, 1st May, 2007
npl(NULL) = -1
If X has zero or one child, npl(X) = 0
Otherwise
1 0
0 0 0 -1
Null
0 -1 -1 -1 0 -1
Null Null Null Null npl(NULL) = -1
-1 -1 -1 -1
Null Null Null Null
• Tree is unbalanced
• Biased towards left
• Left paths are long, giving the name Leftist Tree
• Rightmost path is the shortest
Structural Property
T1 T2
2 2
0 0 0 0 0 0 0 1
0 0
If X is root
Parent (X) = root
Binary Heap vs. Leftist Heap
Proof is by Induction
This gives
N ≥ 2r − 1 ⇒ r ≤ log2 (n + 1)
Structure of a Node
Left Right
Data NPL
Pointer Pointer
Internal
Node
Internal
1 0
Node
0 0 0 -1
0 -1 -1 -1 -1 0
-1 -1 -1 -1 External
Node
• It is a fundamental operation
– Both Insert and DeleteMin are based on Merge
– Insert:
• The key to be inserted is a one-node heap
• Merge this one-node heap with the given min leftist heap
– DeleteMin
• Delete root, left and right child of root are two min leftist heaps
• Merge the two min leftist heaps
Merge Algorithm (Recursive)
Merge(H1, H2)
If both heaps are Leftist
If one heap is NULL then return the other
If data(H1) > data(H1) then swap H1 and H2
If leftChild(H1) is NULL then leftChild(H1) = H2
Otherwise,
Recursively Merge rightChild(H1) and H2
If Leftist Heap Property is violated i.e
If npl( leftChild(H1) ) < npl( rightChild(H1) ) then swap children of
H1
npl(H1) = npl(rightChild(H1)) + 1
Merge H1 & H2
H1 H2
2 2
2 3
1 1 1 1
6 9 5 8
0 0 0 0 0 0 0 0
7 13 17 37 15 11 19 23
0 0 0
41 29 26
Resizing H1
Merge H1 & H2
H2
2 1
2 9
H1
0 0
1 2
6 3 17 37
0
0 0 1 1
7 13 5 8 41
0 0 0 0
15 11 19 23
0 0
29 26
0 0
1 2
6 3 17 37
0
0 0 1 1
7 13 5 8 41
H1
0 0 0 0
15 11 19 23
0 0
29 26
0
1 2
6 3 26
0 0 1 1
7 13 5 8 H1
0 0 0 1
15 11 19 9
0 0 0 0
2929 17 37
0
41
Resizing H1
Merge H1 & H2
H2
2 0
2 23 0 091H2
17 37410
0
1 2
6 3 26
0 0 1 1
7 13 5 8 H1
0 0 0 1
15 11 19 9
0 0 0
29 17 37
0
41
0
1 2
6 3 26
0 0 1 1
7 13 5 8
0 0 0 1
15 11 19 9 H1
0 0 0
29 17 37
0
41
0
1 2
6 3 41
0 0 1 1
7 13 5 8
0 0 0 1
15 11 19 9 H1
0 0 0
29 17 23
0
26
NULL
Since, leftChild(H1) ≠ NULL
H1 now points to its rightChild — NULL
Merge H1 & H2
H2
2 0
H1 is NULL
2 37
0
1 2
6 3 41
0 0 1 1
7 13 5 8
0 0 0 1
15 11 19 9
0 0 0
29 17 23 H1
0
26
NULL
Merge (H1, H2)
0 0
26 37
0
41
NULL
Merge H1 & H2
Leftist Heap Property NOT Violated
2
2
1 2
6 3
0 0 1 1
7 13 5 8 Adjust Null
H1Path Lengths
points to '37'
0 0 0 1 from the Last Node
15 11 19 9 on the Rightmost Path
0 0 0 to the Root
29 17 23 H1
0 00
26 37
00
41
NULL npl (NULL) = -1
leftChild(H1)→npl ≥ rightChild(H1)→npl — 0 ≥ -1
H1→npl = rightChild(H1)→npl + 1 = '0'
Merge H1 & H2
Leftist Heap Property NOT Violated
2
2
1 2
6 3
0 0 1 1
7 13 5 8
H1 moves up to '23'
0 0 0 1
15 11 19 9
0 0 10*
0
29 17 23 H1
0 0
26 37
0
41
NULL npl (NULL) = -1
leftChild(H1)→npl ≥ rightChild(H1)→npl — 0 ≥ 0
H1→npl = rightChild(H1)→npl + 1 = '1'
Merge H1 & H2
Leftist Heap Property Violated
2
swap( leftChild(H1), rightChild(H1) )
2
1 2
6 3
0 0 1 1
7 13 5 8
H1 moves up to '9'
0 0 0 1*
1
15 11 19 9 H1
0 0 11
29 17 23
0 0
26 37
0
41
leftChild(H1)→npl ≥ rightChild(H1)→npl — 0 ≤ 1
Merge H1 & H2
Leftist Heap Property Violated
2
swap( leftChild(H1), rightChild(H1) )
2
1 2
6 3
0 0 1 1
7 13 5 8 H1
H1 moves up to '9'
0 0 0 11*
15 11 19 9
0 0 1
29 17 23
0 0
26 37
0
41
leftChild(H1)→npl ≥ rightChild(H1)→npl — 0 ≤ 1
H1→npl = rightChild(H1)→npl + 1 = '1'
Merge H1 & H2
Leftist Heap Property Violated
2
swap( leftChild(H1), rightChild(H1) )
2
1 2
6 3
0 0 1 11*
1
7 13 5 8 H1
H1 moves up to '8'
0 0 00 11
15 11 19 9
0 0 11 0
0
2929 23 17
17
00 00
37
26 37
26
00
41
41
leftChild(H1)→npl ≥ rightChild(H1)→npl — 0 ≤ 1
H1→npl = rightChild(H1)→npl + 1 = '1'
Merge H1 & H2
Leftist Heap Property NOT Violated
2
2
1 2
6 3 H1
0 0 1 11
7 13 5 8
0 0 0
H1 moves up to '3'
1
0
15 11 9 19
1 0 0
23 17 29
0 0
26 37
0
41
leftChild(H1)→npl ≥ rightChild(H1)→npl — 1 ≥ 1
H1→npl = rightChild(H1)→npl + 1 = '2'
Merge H1 & H2
Leftist Heap Property Violated
2*
2
2
swap( leftChild(H1), rightChild(H1) )
2 H1
1 2
6 3
0 0 1 1
7 13 5 8
0 0 0
H1 moves up to '2'
0
15 11 9 19
1 0 0
23 17 29
0 0
26 37
0
41
leftChild(H1)→npl ≥ rightChild(H1)→npl — 1 ≤ 2
H1→npl = rightChild(H1)→npl + 1 = '2'
Merge H1 & H2 H1
Root
22
2
2 1
3 6
1 1 0 0
5 8 7 13
H1 is returned
0 0 0 0
Root pointer now points to H1
15 11 9 19
1 0 0
23 17 29
0 0
26 37
0
41
Merge Algorithm (Iterative)
Merge(H1, H2)
H1 — existing Heap
H2 — one-node heap containing node to be inserted
Both H1 and H2 are Min Leftist Heaps
Insert 3
H1
H1 H2
22
Both H1 and H2 are not NULL 0
2 3
11 11
6 9
00 00 00 00
7 13 17 37
00
41
6 33 17 37
00 00 1 0
7 13 9
NULL 41
0 0
17 37
0
41
leftChild(H1)→npl ≥ rightChild(H1)→npl — 1 ≥ -1
H1→npl = rightChild(H1)→npl + 1 = '0'
Insert 3
12*
2
2 H1 H1 moves up to '2'
1 0
6 3
0 0 1
7 13 9 NULL npl (NULL) = -1
0 0
17 37
Leftist Heap Property NOT Violated
0
41
leftChild(H1)→npl ≥ rightChild(H1)→npl — 1 ≥ 0
H1→npl = rightChild(H1)→npl + 1 = '1'
Insert 3
Root H1
11
2 H1 is returned
1 0 Root pointer now points to H1
6 3
0 0 1
7 13 9
0 0
17 37
0
41
Time Complexity of Insert
• O(log n)
2
2
1 1
6 9
0 0 0 0
7 13 17 37
0
41
22
H1
22 H2
1 1
6 9
0 0 0 0
7 13 17 37
0
41
H1
2
H2
1 1
6 Both H1 and H2 are not NULL 9
0 0 0 0
7 13 17 37
0
41
H1
2
H2
1 1
6 H1 9
0 0 0 0
7 13 17 37
0
41
2
2
H2
1 1
6 Both H1 and H2 are not NULL 9
H1
0 0 0 0
7 13 17 37
0
41
2
2
H2
1 0
6 H1 13
0 1
7 9
0 0
17 37
0
41
2
2
H2
1 0
6 Both H1 and H2 are not NULL 13
0 1
7 9 H1
0 0
17 37
0
41
2
2
H2
1 0
6 37
0 1 0
7 9 H1 41
0 0
17 13
0
37
NULL
0
41
2
Adjust Null Path Lengths 2
H2
from the last node
1
on the Rightmost Path H2 is NULL
6
to the Root NULL
0 1
7 9 H1
0 0
17 13
0
37
0
41
DeleteMin
oldRoot
2
Adjust Null Path Lengths 2 H1 points to '13'
from the last node
1
on the Rightmost Path
6
to the Root
0 1
7 9 H1
0 0
17 13
Leftist Heap Property NOT Violated
0
37 NULL npl (NULL) = -1
0
41
leftChild(H1)→npl ≥ rightChild(H1)→npl — 0 ≥ -1
H1→npl = rightChild(H1)→npl + 1 = '0'
DeleteMin
oldRoot
2
2 H1 moves up to '9'
1
6
0 1
7 9 H1
0 0
17 13
Leftist Heap Property NOT Violated
0
37 NULL npl (NULL) = -1
0
41
leftChild(H1)→npl ≥ rightChild(H1)→npl — 0 ≥ 0
H1→npl = rightChild(H1)→npl + 1 = '1'
DeleteMin
oldRoot
2
2 H1 H1 moves up to '6'
11*
1
6 H1
00 1
1
7 9
00 0
0
17 13
Leftist Heap Property Violated
0
swap( leftChild(H1), rightChild(H1) ) 0
37
00
41
leftChild(H1)→npl ≥ rightChild(H1)→npl — 0 ≤ 1
H1→npl = rightChild(H1)→npl + 1 = '1'
DeleteMin
oldRoot
2
2 H1
Root
11
6
1 0
9 7 H1 is returned
0 0 Root pointer now points to H1
17 13 Delete old value of Root
0
37
0
41
Time Complexity of DeleteMin
• O(log n)
Based on Insert
Given N elements, create N one-node min leftist heaps
and insert them into a Queue, Q
Size of Q, |Q| = N
Root = Remove first min leftist heap from queue
while( |Q| > 0 )
Remove one min leftist heaps from queue — H
Insert( H )
Brute Force BuildHeap
0 0 0 0 0 0 0
7 9 37 41 2 6 13
000 00 0 0 0 0 0
77 99 37 41 2 6 13
00
99
Root = 7 |Q| = 6
H=9 |Q| = 5
Insert( H )
Brute Force BuildHeap
Root H
01 00 0 0 0 0
7 37
37 41 2 6 13
0 0
9 37
Root = 7 |Q| = 5
H = 37 |Q| = 4
Insert( H )
Brute Force BuildHeap
Root H
11 0 0 0 0
7 41 2 6 13
0 0
9 37
0
41
Root = 7 |Q| = 4
H = 41 |Q| = 3
Insert( H )
Brute Force BuildHeap
Root H
1
0 00 0 0
7
2 22 6 13
11
0 0
7
9 37
00 0
0
9 37
41
00
41
Root = 7 |Q| = 3
H=2 |Q| = 2
Insert( H )
Brute Force BuildHeap
Root H
011 00 0
22 66 13
111 00
77 6
000 000
99 37
37
000
41
41
Root = 7 |Q| = 2
H=6 |Q| = 1
Insert( H )
Brute Force BuildHeap
Root H
11 00
2 13
13
11 1 0 00
7 7 6 6
00 0 00 0 00
9 9 37 37 13
00 0
41 41
Root = 7 |Q| = 1
H = 13 |Q| = 0
Insert( H )
Time Complexity of
Brute Force BuildHeap
• O(N log N)
1 insert — O(log N)
N inserts — O(N log N)
Efficient BuildHeap
• O(N) time
Based on Merge
Given N elements, create N one-node min leftist heaps
and insert them into a Queue, Q
Size of Q, |Q| = N
while( |Q| > 1 )
Remove first two min leftist heaps from queue — H1 and H2
Merge H1 and H2
Insert merged min leftist heap into queue
Efficient BuildHeap
0 0 0 0 0 0 0
7 9 37 41 2 6 13
00 00 0 0 0 0 0 0
77 99 37 41 2 6 7 13
0 0
9 9
Remove and merge first two min leftist heaps from queue
H1 = 7 |Q| = 6
H2 = 9 |Q| = 5
H1 = Merge(H1, H2)
Insert H1 into queue |Q| = 6
Efficient BuildHeap
H1 H2
00 00 0 0 0 0 0
37
37 41
41 2 6 13 37 7
0 0 0
41 41 9
Remove and merge first two min leftist heaps from queue
H1 = 37 |Q| = 5
H2 = 41 |Q| = 4
H1 = Merge(H1, H2)
Insert H1 into queue |Q| = 5
Efficient BuildHeap
H1 H2
00 00 0 0 0 0
22 66 13 7 2 37
0 0 0 0
6 9 6 41
Remove and merge first two min leftist heaps from queue
H1 = 2 |Q| = 4
H2 = 6 |Q| = 3
H1 = Merge(H1, H2)
Insert H1 into queue |Q| = 4
Efficient BuildHeap
H1 H2
00
1 0 0 1 0
7
13
13 7 37 7 2
0 0 0 0 0 00
9 13 9 41 9 613
Remove and merge first two min leftist heaps from queue
H1 = 13 |Q| = 3
H2 = 7 |Q| = 2
H1 = Merge(H1, H2)
Insert H1 into queue |Q| = 3
Efficient BuildHeap
H1 H2
1
0 0 1 1
2
37 2 2 7
0 0 0 0 00 0
41
6 37 6 6 937 13
0 0
41 41
Remove and merge first two min leftist heaps from queue
H1 = 37 |Q| = 2
H2 = 2 |Q| = 1
H1 = Merge(H1, H2)
Insert H1 into queue |Q| = 2
Efficient BuildHeap
H1 H2
1 1 11
2
7 2 2
01 00 1 00 0 00
97 13
6 7 66 37
0 0 0 0 00
9 13 9 13 41
0 0
37 37
0 0
41 41
Remove and merge first two min leftist heaps from queue
H1 = 7 |Q| = 1
H2 = 2 |Q| = 0
H1 = Merge(H1, H2)
Insert H1 into queue |Q| = 1
Efficient BuildHeap
Root
1
2
1 0
7 6
0 0
9 13
0
37
0
41
׃
N/2k = 1 k
Time Complexity of Efficient
BuildHeap
Total Time for BuildHeap
N N N N
= ( * 1) + ( * 2) + ( * 3) + + ( k * k)
2 4 8 2
1 1 1 1
= N( + + + k)
2 4 8 2
k
i
= N∑ i
i=1 2
∞
i
= N∑ i
i=1 2
= 3n for n ≥ 3
= Ο(N)