Documente Academic
Documente Profesional
Documente Cultură
Part of this lecture was organized by the instructors at the University of Manitoba in Canada and has been modified by Dr. Ahmad Reza Hadaegh
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 1
Trees
A tree is a linked data structure which reflects some hierarchical structure There are several varieties of trees Each with its own characteristics A family of related data structures
National University
Page
Trees
A tree gets its name from its structure which is tree-like A tree has a root, branches, leaves
Root node
A C F I G
Branches
B E
D H
J
Page 3
Leaf nodes
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University
Trees
A tree consists of a number of connected nodes The nodes are organized in a top-down hierarchical manner
A tree is an instance of a general structure called a graph A graph consists of vertices (nodes) and edges (branches), but is not necessarily hierarchical in nature Sometimes tree and graph terminology is interchanged
National University
Page
Trees
A B
C
F I G
D H J
This tree has 10 nodes, 9 branches, 1 root node, and 6 leaf nodes
National University
Page
Trees
Other defining characteristics If node A points to node B, then A is the parent of B Furthermore, B is the child of A Children of the same parent are siblings All nodes beneath a given node (children, children of children, ) are descendants of that node All nodes on the path between the root and a given node are ancestors of that node
National University
Page
Trees
A B E F I The parent of G is D and the parent of E is B The children of A are B, C, and D B, C, and D are sibling The ancestors of J are G, D, and A The descendants of D are G, H, I and J
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 7
C G
D H J
Trees
Some typical operations upon a tree Insert Add a new node into a tree Delete Remove a node from a tree Search Find a node (if it exists) that contains a given key
Binary Trees
Binary trees A binary tree is a tree in which no node has more than two children A B D E G
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University
C F H
Page 9
National University
Page 10
A B
C
E G F H
National University
Page 11
D B
E
C F G H
National University
Page 12
D C
F
E G H
A
B
National University
Page 13
A B C D E
F
G H
National University
Page 14
National University
Page 15
Searching a BST
Searching a BST Algorithm Start with root node if search key = node key then stop else if search key < node key then go left else go right Stop if at any time during the search, you fall off the tree, stop
National University
Page 16
Searching a BST
Find node with key C
D B
E
C F G ` H
National University
Page 17
Searching a BST
Find node with key X
D B
E
C F G H
National University
Page 18
Searching a BST
Given an existing BST, searching for a key is simple Effectively a binary search Is it as efficient as a binary search? Algorithm is recursive, but can be trivially implemented iteratively Could be implemented as follows:
National University
Page 19
Searching a BST
bool Search(nodeptr curr, char key) { bool found; nodeptr curr; curr = root; found = false; while ((curr != NULL) && (! found)) if (curr->data == key) found = true; else if (key < curr->data) curr = curr->left; else curr = curr->right; return found; }
Traversing a Tree
Tree traversal is a common operation Traversal of a tree can be divided into two category: Depth-First Traversal and Breadth-First Traversal Three common types of depth-first traversal are: Pre-order, post-order, and in-order traversal Depth-First Traversal can be easily done recursively We can also use stack operation to print a traverse a tree Breath-First traversal can be done with Queue
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 21
Post-order traversal Perform a Post-order traversal of the left sub-tree Perform a Post-order traversal of the right sub-tree Visit the current node
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 22
void InOrderTraversal (NodePtr root) { if (root = = NULL) return; InOrder(root->left); cout << root ->data << endl; InOrder(root->right); } void PreOrderTraversal (NodePtr root) { if (root = = NULL) return; cout << root ->data << endl; PreOrder(root->left); PreOrder(root->right); } void PostOrderTraversal (NodePtr root) { if (root = = NULL) return; PostOrder(root->left); PostOrder(root->right); cout << root ->data << endl; }
National University
Page 23
Breadth-First Traversal
D B A C E
G ` F
H
In Breadth-First traversal, all the nodes in the first level are printed, followed by the nodes in second level, followed by the nodes in the third level and so on.
National University
Page 28
National University
Page 29
MorrisInOrder() { P = Root while not finished if P has no left descendant { visit it; P = P->Right; } else { Temp = the right child of the rightmost node in its left descendant of P
Temp
Temp->Right = P;
P = Root } }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 30
P 10 5 3 7 Temp 20 3
P 5 7 Temp 3 Temp
P 5 7 10 20
10
Step 1
P 3 Temp 5 7 10
Step 2
Step 3
20
Now we can print the linked list. The nodes are organized in in-order form like a singular linked list
20
National University Page 31
Step 4
A.R. Hadaegh Dr. Ahmad R. Hadaegh
Temp 5
P
7 10 3 Temp
3 Temp 10
7
P 10
Step 5
5 Temp
20
Step 6
Temp 10 5
20
Step 7
Temp 10 5 3 7
20
20 7
20
10
P 3 P=NULL
Step 8
20
Step 9
Step 10
Now the tree is back to its original shape after the traversal is done
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 32
Insertions
Binary trees are normally created by inserting nodes into an initially empty tree If tree empty, first insert will create the root node Otherwise, tack new node onto the (unique) appropriate node that has less than 2 children This will require a search routine
National University
Page 33
Insert 15, 8, 12, 19, 5, and 23 into an empty BST 15 8 Step 1 Step 2 Step 3 15 8 12 15
15
8 19 8 5 Step 5
15
19 12 5 Step 6
National University
15
8 19
12
Step 4
A.R. Hadaegh Dr. Ahmad R. Hadaegh
12
23
Page 34
// This procedure implements a recursive insert. // it can also be done iteratively. void insert (nodeptr& root, nodeptr newnode) { if (root == null) root = newnode; else if (newnode->data < root->data) insert (root->left, newnode); else insert (root->right, newnode); }
National University
Page 35
void Tree::InsertWithNoRecursion(TreeStructPtr& Root, int x) { TreeStructPtr p = Root, prev=Root; while (p != NULL) This is the implementation { prev = p; if (x < p->Number) of the insert function p = p->Left; without using Recursion else if (x > p->Number) p = p->Right; else { cout << "\n!!!! " << x << " is already in the tree " << endl; return; } } TreeStructPtr NewNode; NewNode = new (TreeStruct); NewNode->Number = x; NewNode->Left = NULL; NewNode->Right = NULL; if (Root = = NULL) Root = NewNode; else if (prev->Number < x) prev->Right = NewNode; else prev->Left = NewNode; return; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 36
Deletions
Deleting is a little more difficult. Why? When deleting from a BST, the algorithm must often reorganize tree while maintaining the inherent ordering Three cases to consider
National University
Page 37
Case 1: Deleting a leaf node This is easy -- detach leaf node from tree by setting its parents pointer to nil For example, suppose we want to delete 12 15 8 5 12 19 23 15 ` 5 8 12 15 ` 19 23
8
5
A.R. Hadaegh Dr. Ahmad R. Hadaegh
19 23
National University Page 38
Case 2: Deleting a node with a single child Easy -- replace the node to be deleted with its child For example, suppose we want to delete 19 15 8 5 12 19 23 15 5 8 12 15 19 23
8
5
A.R. Hadaegh Dr. Ahmad R. Hadaegh
23 12
National University Page 39
Case 3: Deleting a node with two Children For example, suppose we want to delete 21
12 8 7 10 17 21 23
14
19
22
26
National University
Page 40
There are Two possible algorithms for delete Method 1: Replace the deleted node with one of its children, say the left child (i.e. node 17) The remaining right child (i.e. node 23) must now be linked back into the tree Place it on the right of the largest node of the new left subtree
National University
Page 41
Replace the deleted node with one of its children, say the left child (i.e. node 17)
12
8 7 10 21
17
23
14
19
22
26
National University
Page 42
12 8 7 10 17 23
14
19
22
26
National University
Page 43
Place it (node 23) on the right of the largest node of the new left subtree
12 8 7 10 17 23
14
19
22
26
National University
Page 44
Done!
12
8
7
17
10
14
19
23
22
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University
23
Page 45
Deletions
Method 2: Locate the in-order successor of the node to be deleted (the node that contains the next highest value) To locate the in-order successor, go right, then go left as far as possible
Replace the contents of the node to be deleted with the contents of its in-order successor
Delete the successor node This algorithm is possible since the in-order successor node will never have more than one child
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 46
Delete 21
12 8 7 10 17 21 23
14
19
22
26
National University
Page 47
Replace the contents of the node to be deleted with the contents of its in-order successor
12 8 7 10 17 21 23
14
19
22
26
National University
Page 48
Now swap the value of the node with the value of its successor node
12 8 7 10 17 22 23
14
19
21
26
National University
Page 49
12
8
7 10 17
22 23
14
19
21
26
National University
Page 50
Deletions
Done!
12 8 7 10 17 22 23
14
19
26
National University
Page 51
An alternative approach to the second method is to find predecessor of a node instead of the successor node. This mainly works the same as the second method Another issue to consider is that the second method does not change the structure of the tree as much as the first method does. The height of the tree does not change as much in the second method compare to the first method
However, if we keep applying the second method for deletion and choose successor node to replace with the node, the tree eventually becomes unbalanced
One way to improve the second method is we can write the algorithm to alternatively delete the predecessor of the node from the left subtree and delete the successor from the right subtree
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 52
P K B
1 1 0
1 2 3
0 1 3
K
D P
Because there is at least one node (node B) with the difference value of 3, this tree is not balanced
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University
R
Page 53
Suppose we receive a set of data all in one shot and we want to insert them into a binary tree such that the end result is a balanced binary search tree. If we insert the data one by one randomly, the tree may not turn to be a balanced binary search tree. One method to solve this problem is to First sort the data using the best sort algorithm available Designate the middle element to be the root of the binary tree The array would consist of two sub arrays: one from the first element to the middle element (the root) but not including the middle element Another consists of middle + 1 till the last element Now the left child of the tree is taken from the middle of the first sub-array and its right child from the middle of the second sub-array Now divide the first sub-array into two other sub-arrays and repeat the same process Similarly divide the other sub-array into two other sub-arrays and repeat the same process
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 54
void Tree:: Balance (T data[ ], int first, int last) { if (first <=last) { int middle = (first + last) /2; insert (data[middle]); Balance (data, first, middle-1) Balance(data, middle+1, last); } }
National University
Page 55
Step 1
0 1 2 3 4 5 6 7 8 9
4
Step 2
2 3
4 4
National University
Page 56
Step 3
2 3
4 4
1 0
Step 4
1 2 3 4 5 6 7 8 9
4
1
0
A.R. Hadaegh Dr. Ahmad R. Hadaegh
2
National University Page 57
Step 5
2 3
4
4
1 0
2
3
Step 6
1 2 3 4 5 6 7 8 9
4 1 0 2 3 7
National University
Page 58
Step 7
2 3
4
4
1 0 2 3 5
Step 8
2 3
4
4
1 0
2 5
3
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University
6
Page 59
Step 9
2 3
4
4
1 0 2 3 5
7 8 6
Step 10
2 3
4
4
1 0 2 3
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University
5
6
8
9
Page 60
What if we already have a balanced binary search tree and we want to insert another element such that after insertion the tree remains balanced One solution is to sort all elements including the new one again and then re-insert the elements again to the tree as we discussed before. Another solution proposed by C. Day and later improved by Q. Stout and B. Warren. Their solution is known as DSW algorithm DSW algorithm avoids sorting. It acquires deconstructing and reconstructing of the tree The building block for the tree transformation in this algorithm is the rotation
National University
Page 61
There are two types of rotations: Left rotation and Right Rotation which are symmetrical to one another The right rotation of a node called Child around its parent node called Parent is performed according to the following algorithm RotateRight (Grandparent, Parent, Child) { - If Parent is not the root of the tree Grandparent of child becomes childs parent by replacing the parent - Right subtree of child becomes left subtree of childs parent
National University
Page 62
Gr
Ch b c Par a
Gr Par a b
A.R. Hadaegh Dr. Ahmad R. Hadaegh
Gr
Left rotation of Ch around Par
Ch Par c b
Page 63
Ch c
National University
DSW algorithm transforms an arbitrary binary search tree into a linked list like tree called a backbone tree Then the backbone tree is transformed in a series of passes into a perfectly balanced tree by repeatedly rotating every second node of the backbone around its parent
5
5
10 20 15 25 23 28 30 40
25 10 15
20
23 25 28 30 40 5 10
20
30
23
28
40
15
National University
Page 64
In the first phase, the backbone is created using the following algorithm: createBackbone(root, n) { tmp = root; while (tmp != NULL) if tmp has a left child { rotate this child around tmp; set tmp to the child which just became parent } else set tmp to its right child
National University
Page 65
tmp 5 10 5 10 tmp 20 30 25 23 28 40 23 15 25 28 30
5 10 tmp
20
15
15 20
30 40
25
23 28
40
National University
Page 66
5
10 tmp 15 20 30 25 23 28 40
5 10 15 20
5 10 15
20 tmp
30
tmp 25
25
23 28
40
23
30
28
40
National University
Page 67
5 5 10 10 10 5
15
20
15
tmp 25 20 tmp 25
15 20 tmp 23 30
23
30
23
28 40
25
40
28
30
28 40
National University
Page 68
5 10
15 20 tmp 23 25 30 28 40 10 15 20 23
5 10 15 20 23 25
5
10 15 20 23
25
tmp 30 tmp 28 30
25 28 30
28
40
40
40 tmp=NULL
National University
Page 69
In the second phase, the Backbone is transformed into a tree but this time the tree is perfectly balanced by having leaves on two adjacent levels In each pass down the backbone, every second node down to a certain point is rotated around its parent The algorithm is as follows:
createPerfectTree(n) { m = 2 lg(n+1) -1 Make n m rotations starting from the top of the backbone while (m >1) { m = m/2 make m rotations starting from the top of the backbone } }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 70
Step 1
5 10 10
Step 2
20
Step 3
10
25 23 30 28 m = 3/2 = 1 40
15
5 20 15 23 25
20
23 25 28
15
28
30 30 40 n=9 m=7 So we need to do nm=2 rotations
A.R. Hadaegh Dr. Ahmad R. Hadaegh
Step 4
25 30
23
28
40
National University
1 2 4 3 7 6 8
9
10
Some of the code in this lecture is placed in example 1 for the tree lecture in the web
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 72