1.1k likes | 1.33k Views
Chap 5. Trees. Definition: A tree is a finite set of one or more nodes such that: There is a specially designated node called the root.
E N D
Chap 5 Trees
Definition: A tree is a finite set of one or more nodes such that: There is a specially designated node called the root. The remaining nodes are partitioned into n ≥ 0 disjoint sets T1, …, Tn, where each of these sets is a tree. We call T1, …, Tn the subtrees of the root. Trees
Pedigree Genealogical Chart Cheryl Rosemary Kevin Kelly Richard John Terry Jack Anthony Michelle Mary Karen Joe Mike Angela Binary Tree
Lineal Genealogical Chart Proto Indo-European Italic Hellenic Germanic Osco-Umbrian Latin Greek North Germanic West Germanic Osco Umbrian Spanish French Italian Icelandic Norwegian Swedish Low High Yiddish
Normally we draw a tree with the root at the top. The degree of a node is the number of subtrees of the node. The degree of a tree is the maximum degree of the nodes in the tree. A node with degree zero is a leaf or terminal node. A node that has subtrees is the parent of the roots of the subtrees, and the roots of the subtrees are the children of the node. Children of the same parents are called siblings. Tree Terminology
The ancestors of a node are all the nodes along the path from the root to the node. The descendants of a node are all the nodes that are in its subtrees. Assume the root is at level 1, then the level of a node is the level of the node’s parent plus one. The height or the depth of a tree is the maximum level of any node in the tree. Tree Terminology (Cont.)
A Sample Tree Level A 1 2 B C D 3 E F G H I J 4 K L M
List Representation of Trees The tree in previous slide could be written as (A (B (E (K, L), F), C(G), D(H (M), I, J))) A 0 B F 0 C G 0 D I J 0 E K L 0 H M 0
Lemma 5.1: If T is a k-ary tree (i.e., a tree of degree k) with n nodes, each having a fixed size as in Figure 5.4, then n(k-1) + 1 of the nk child fileds are 0, n ≥ 1. Possible Node Structure For A Tree of Degree Child k … Child 4 Child 3 Child 2 Child 1 Data Wasting memory!
Left Child-Right Sibling Representation Each node has two links (or pointers). Each node only has one leftmost child and one closest sibling. Representation of Trees A data left child right sibling B C D E F G H I J K L M
Degree Two Tree Representation A B C E F K G D Binary Tree! L H M I J
Tree Representations A A A B B B A A A B C B B C C Left child-right sibling Binary tree
Definition: A binary tree is a finite set of nodes that is either empty or consists of a root and two disjoint binary trees called the left subtree and the right subtree. There is no tree with zero nodes. But there is an empty binary tree. Binary tree distinguishes between the order of the children while in a tree we do not. Binary Tree
A A B B Binary Tree Examples A A B B C C D E F G D H I E
Lemma 5.2 [Maximum number of nodes] The maximum number of nodes on level i of a binary tree is 2i-1, i ≥ 1. The maximum number of nodes in a binary tree of depth k is 2k – 1, k ≥ 1. Lemma 5.3 [Relation between number of leaf nodes and nodes of degree 2]: For any non-empty binary tree, T, if n0 is the number of leaf nodes and n2 the number of nodes of degree 2, then n0 = n2 + 1. Definition: A full binary tree of depth k is a binary tree of depth k having 2k – 1 nodes, k ≥ 0. The Properties of Binary Trees
Definition: A binary tree with n nodes and depth k is complete iff its nodes correspond to the nodes numbered from 1 to n in the full binary tree of depth k. Binary Tree Definition level 1 1 2 2 3 3 6 4 7 5 4 12 13 8 9 14 15 10 11
Array Representation of A Binary Tree • Lemma 5.4: If a complete binary tree with n nodes is represented sequentially, then for any node with index i,1 ≤ i ≤ n, we have: • parent(i) is at if i ≠1. If i = 1, i is at the root and has no parent. • left_child(i) is at 2i if 2i ≤ n. If 2i > n, then i has no left child. • right_child(i) is at 2i + 1 if 2i + 1 ≤ n. If 2i + 1 > n, then i has no right child. • Position zero of the array is not used.
Assume that for all j, 1≤ j ≤ i, left_child(j) is at 2j. Then two nodes immediately preceding left_child(i + 1) are the right and left children of i. The left child is at 2i. Hence, the left child of i + 1 is at 2i + 2 = 2(i + 1) unless 2(i + 1) > n, in which case i + 1 has no left child. Proof of Lemma 5.4 (2)
A [1] [2] B [3] [4] C [5] [6] [7] [8] D [9] [16] E Array Representation of Binary Trees A [1] [2] B C [3] [4] D [5] E [6] F G [7] [8] H I [9]
class Tree; class TreeNode { friendclass Tree; private: TreeNode *LeftChild; char data; TreeNode *RightChild; }; class Tree { public: // Tree operations . private: TreeNode *root; }; Linked Representation
Node Representation data LeftChild RightChild LeftChild data RightChild
A E H 0 I 0 Linked List Representation For The Binary Trees root root A 0 B 0 C B C 0 D F 0 G 0 D 0 0 E 0
When visiting each node of a tree exactly once, this produces a linear order for the node of a tree. There are 3 traversals if we adopt the convention that we traverse left before right: LVR (inorder), LRV (postorder), and VLR (preorder). When implementing the traversal, a recursion is perfect for the task. Tree Traversal
Binary Tree With Arithmetic Expression + * E * D / C A B
Inorder Traversal: A/B*C*D+E => Infix form Preorder Traversal: +**/ABCDE => Prefix form Postorder Traversal: AB/C*D*E+ => Postfix form Tree Traversal
Inorder traversal template <class T> void Tree <T>::Inorder() {//Driver calls workhorse for traversal of entire tree. Inorder(root); } template <class T> void Tree <T>::Inorder (TreeNode <T> *currentNode) {//Workhouse traverses the subtree rooted at currentNode. If (currentNode){ Inorder(currentNode->leftChild); Visit(currentNode); Inorder(currentNode->Child); } }
void Tree::NonrecInorder() // nonrecursive inorder traversal using a stack { Stack<TreeNode *> s; // declare and initialize stack TreeNode *CurrentNode = root; while (1) { while (CurrentNode) { // move down LeftChild fields s.Add(CurrentNode); // add to stack CurrentNode = CurrentNode->LeftChild; } if (!s.IsEmpty()) { // stack is not empty CurrentNode = *s.Delete(CurrentNode); cout << CurrentNode->data << endl; CurrentNode = CurrentNode->RightChild; } elsebreak; } } Iterative Inorder Traversal
All previous mentioned schemes use stacks. Level-order traversal uses a queue. Level-order scheme visit the root first, then the root’s left child, followed by the root’s right child. All the node at a level are visited before moving down to another level. Level-Order Traversal
void Tree::LevelOrder() // Traverse the binary tree in level order { Queue<TreeNode *> q; TreeNode *CurrentNode = root; while (CurrentNode) { cout << CurrentNode->data<<endl; if (CurrentNode->LeftChild) q.Add(CurrentNode->LeftChild); if (CurrentNode->RightChild) q.Add(CurrentNode->RightChild); CurrentNode = *q.Delete(); } } Level-Order Traversal of A Binary Tree +*E*D/CAB
Use of parent field to each node. Use of two bits per node to represents binary trees as threaded binary trees. Traversal Without A Stack
With the inorder, postorder, or preorder mechanisms, we can implement all needed binary tree functions. E.g., Copying Binary Trees Testing Equality Two binary trees are equal if their topologies are the same and the information in corresponding nodes is identical. Some Other Binary Tree Functions
The Satisfiability Problem • Expression Rules • A variable is an expression • If x and y are expressions then are expressions • Parentheses can be used to alter the normal order of evaluation, which is not before and before or.
Propositional Formula In A Binary Tree x3 x1 x3 x2 x1 O(g2n)
To evaluate an expression, we can traverse its tree in postorder. To perform evaluation, we assume each node has four fields LeftChild data value RightChild Perform Formula Evaluation LeftChild RightChild value data
For all 2n possible truth value combinations for the n variables { generate the next combination; replace the variables by their values; evaluate the formula by traversing the tree it points to in postorder; if (formula.rootvalue()) {cout << combination; return;} } Cout << “no satisfiable combination”; First Version of Satisfiability Algorithm
void SatTree::PostOrderEval() // Driver { PostOrderEval(root); } void SatTree::PostOrderEval(SatNode * s) // workhorse { if (s) { PostOrderEval(s->LeftChild); PostOrderEval(s->RightChild); switch (s->data) { case LogicalNot: s->value =!s->RightChild->value; break; case LogicalAnd: s->value = s->LeftChild->value && s->RightChild->value; break; case LogicalOr: s->value = s->LeftChild->value || s->RightChild->value; break; case LogicalTrue: s->value = TRUE; break; case LogicalFalse: s->value = FALSE; } } } Evaluating A Formula
Threading Rules A 0 RightChild field at node p is replaced by a pointer to the node that would be visited after p when traversing the tree in inorder. That is, it is replaced by the inorder successor of p. A 0 LeftChild link at node p is replaced by a pointer to the node that immediately precedes node p in inorder (i.e., it is replaced by the inorder predecessor of p). Threaded Binary Tree
Threaded Tree Corresponding to Figure 5.10(b) A B C D E F G H I Inorder sequence: H, D, I, B, E, A, F, C, G
To distinguish between normal pointers and threads, two boolean fields, LeftThread and RightThread, are added to the record in memory representation. t->LeftChild = TRUE => t->LeftChild is a thread t->LeftChild = FALSE => t->LeftChild is a pointer to the left child. Threads
To avoid dangling threads, a head node is used in representing a binary tree. The original tree becomes the left subtree of the head node. Empty Binary Tree Threads (Cont.) LeftThread LeftChild RightChild RightThread data TRUE FALSE
D f f Memory Representation of Threaded Tree of Figure 5.20 - f f A f f B f f B f f t E t f D f t E t H t I t t t
Finding the inorder successor without stack • By using the threads, we can perform an inorder traversal without making use of a stack. T* ThreadedInorderIterator::Next() {//Return the inorder successor of currentnode ThreadedNode <T> *temp = currentNode -> rightChild; if (!currentNode->rightThread) while (!temp->leftThread) temp = temp -> leftChild; currentNode = temp; if (currentNode == root) return 0; else return ¤tNode -> data; }
Inserting a node r as the right child of a node s. If s has an empty right subtree, then the insertion is simple and diagram in Figure 5.23(a). If the right subtree of s is not empty, the this right subtree is made the right subtree of r after insertion. When thisis done, r becomes the inorder predecessor of a node that has a LdeftThread==TRUE field, and consequently there is an thread which has to be updated to point to r. The node containing this thread was previously the inorder successor of s. Figure 5.23(b) illustrates the insertion for this case. Inserting A Node to AThreaded Binary Tree
Insertion of r As A Right Child of s in A Threaded Binary Tree s s r r after before
r Insertion of r As A Right Child of s in A Threaded Binary Tree (Cont.) s s r r after before
void ThreadedTree::InsertRight(ThreadNode *s, ThreadedNode *r) // Insert r as the right child of s { r->RightChild = s->RightChild; r->RightThread = s->RightThread; r->LeftChild = s; r->LeftThread = TRUE; // LeftChild is a thread r->RightChild = r; // attach r to s r->RightThread = FALSE; if (!r->RightThread) { ThreadedNode *temp = InorderSucc(r); // returns the inorder successor of r temp->LeftChild = r; } } Program 5.16 Inserting r As The Right Child of s
In a priority queue, the element to be deleted is the one with highest (or lowest) priority. An element with arbitrary priority can be inserted into the queue according to its priority. A data structure supports the above two operations is called max (min) priority queue. Priority Queues
Suppose a server that serve multiple users. Each user may request different amount of server time. A priority queue is used to always select the request with the smallest time. Hence, any new user’s request is put into the priority queue. This is the min priority queue. If each user needs the same amount of time but willing to pay more money to obtain the service quicker, then this is max priority queue. Examples of Priority Queues
Unorder Linear List Addition complexity: O(1) Deletion complexity: O(n) Chain Addition complexity: O(1) Deletion complexity: O(n) Ordered List Addition complexity: O(n) Deletion complexity: O(1) Priority Queue Representation
Heaps are frequently used to implement priority queues. The complexity is O(log n). Definition: A max (min) tree is a tree in which the key value in each node is no smaller (larger) than the key values in its children (if any). A max heap is a complete binary tree that is also a max tree. A min heap is a complete binary tree that is also a min tree. Max (Min) Heap