630 likes | 734 Views
T:. T 0. T 1. T 2. T m. …. Trees. Definition (recursive): finite set of elements ( nodes ) which is either empty or it is partitioned into m + 1 disjoint subsets T 0 ,T 1 ,…T m where T 0 contains one node ( root ) and T 1 , T 2 …T m are trees. Definitions.
E N D
T: T0 T1 T2 Tm … Trees • Definition (recursive):finite set of elements (nodes) which is either empty or it is partitioned into m + 1 disjoint subsets T0,T1,…Tm where T0 contains one node (root) and T1, T2…Tm are trees Trees
Definitions • Depth of tree node: length of the path from the root to the node • the root has depth 0 • Height of tree: depth of the deepest node • Leaf: all leafs are at level d • Full tree: all levels are full • Complete tree: all levels except perhaps level d are full Trees
A sub-tree B C D E H I J F G K leaf root root (tree) = A descendents (B) = {F,G} sons (B) ancestors (H) = {E} parent (H) degree (tree) = 4: max number of sons degree (E) = 3 level (H) = 2 level (A) = 0 depth (tree) = 3 max level Trees
Τ0 Τleft Τright Binary Trees • Finite set of nodes which is either empty or it is partitioned into sets T0, Tleft, Tright where T0 is the root and Tleft, Tright are binary trees • A binary tree with n nodes at level lhas at most2n nodes at level l+1 Trees
A B C E F G D Full Binary Tree • d: depth • A binary tree has exactly 2lnodes at level l<= d • Total number of nodes: N = 2d+1 –1 • N= all leaf nodes at the same level Trees
Binary Tree Traversal • Traversal: list all nodes in order • preorder (depth first order): root traverse Tleftpreorder traverse Tright preorder • inorder(symmetric order): traverse Tleftinorder root traverse Tright inorder • postorder: traverse Tleft traverse Tright root Trees
preorder: ABDGCEHIF inorder: DGBAHEICF postorder: GDBHIEFCA A C B F E D I H G Trees
preorder:ABCEIFJDGHKL inorder:EICFJBGDKHLA postorder:IEJFCGKLHDBA A B C D E F G H I J L K Trees
T0 T1 T2 TΜ … Traversal of Trees of Degree >= 2 • preorder • T0 (root) • T1preorder • T2preorder • … • TMpreorder inorder • T1inorder • T0 (root) • T2inorder • … • TMinorder postorder • T1postorder • T2postorder • … • TMpostorder • T0 (root) Trees
A B F C D E G H preorder:ABCDHEFG inorder:CBHDEAGF postorder:CHDEBGFA Trees
Binary Tree Node ADT template <class BELEM> class BinNode{ public: BinNode* leftchild( ) const; //pointer to left child BinNode* rightchild( ) const //pointer to right child BELEM value( ) const; //node value void setValue(BELEM val); //set node value bool isLeaf( ) const; //check if node is a leaf }; Trees
Binary Tree Node Class enum bool {true = ‘1’, false=‘0’}; template <class BELEM> class BinNode{ private: BELEM element; BinNode *left, *right; public: BinNode ( ) {left = right = NULL;} //constructors BinNode (BELEM e,BinNode *l = NULL,BinNode *r = NULL) {element = e; left = l; right = r; } ~BinNode ( ) { } //destructor BinNode<BELEM> *leftchild ( ) const { return left; } Trees
Binary Tree Node Class (cont.) BinNode<BELEM> *rightchild ( ) const { return right; } BELEM value ( ) const { return element;} void setValue (const BELEM& val) {element = val;} bool isLeaf ( ) const { return (left == NULL ) && ( right == NULL);} bool isLeft (BinNode<BELEM>*p) {… } } Trees
Binary Tree Traversal template <class BELEM> void preorder(BinNode<BELEM>*tree){ if (tree == NULL) return; else { cout<<‘’node:‘’<<treeelement <<‘’\n‘’; preorder ( treeleftchild ( ) ); preorder (treerightchild ( ) ); } } Trees
10 3 20 1 15 30 25 Binary Search Tree (BST) • Each node stores key K • The nodes of Tleft have keys < K • The nodes of Tright have keys >=K Trees
50 60 30 65 20 35 Search in BST • Compare with root • If x == root(key) => key found !! • If x< key(root) search the Tleft recursively • If x>=key(root) search Tright recursively Trees
50 60 30 max min 65 20 35 Find Min/Max Key • Find the maximum key in a BST: follow nodes on Tright until key is found or NULL • Find the minimum key in a BST: follow nodes on Tleft Trees
50 60 30 65 20 35 ρ 40 37 Insert Key in BST • Search until a leaf is found • insert it as left child of leaf if key(leaf) < x • insert it as right child of leaf if key(leaf) >= x Trees
10 5 20 1 7 1 5 7 10 20 Shape of BST • Depends on insertion order • For random insertion sequence the BST is more or less balanced • e.g., 10 20 5 7 1 • For order insertion sequence the BST becomes list • e.g., 1 5 7 10 20 Trees
Delete key x from BST • Three cases: • X is a leaf: simply delete it • X is not a leaf & it has exactly one sub-tree • the father node points to the node next to x • delete node(x) • X is not a leaf & it has two sub-trees • find p: minimum of Trightor maximum of Tleft • this has at most one sub-tree!! • delete it as in (a) or (b) • substitute x with p Trees
a) The key is a Leaf Trees
50 60 30 65 35 20 40 37 BST Sorting • Insert keys in BST • Insertion sequence: 50 30 60 20 35 40 37 65 • Output keys inorder • Average case: O(nlogn) • Worst case: O(n2) Trees
Implementation of BSTs • Each node stores the key and pointers to roots of Tleft, Tright • Array-based implementation: • known maximum number of nodes • fast • good for heaps • Dynamic memory allocation: • no restriction on the number of nodes • slower but general Trees
Dynamic Memory Allocation • Two C++ classes • BinNode: node class (page 12) • node operations: left, right, setValue, isleaf, father … • BST: tree class • composite operations: find, insert, remove, traverse … • Use of “help” operations: • easier interface to class • encapsulation: implementation becomes private Trees
BST Class template <class BELEM> class BST{ private: BinNode<BELEM> *root; void inserthelp (BinNode <BELEM> *&, const BELEM); void removehelp(BinNode <BELEM> *&,const BELEM); BinNode <BELEM> * findhelp (BinNode <BELEM> *,const BELEM) const; void printhelp (const BinNode <BELEM> *,const int)const; void clearhelp (BinNode <BELEM> *); public: BST ( ) { root = NULL; } ~BST ( ) { clearhelp (root); } void clear ( ) { clearhelp (root); root = NULL;} void insert (const BELEM & val) { inserthelp (root, val); } Trees
BST Class (cont.) void remove (const BELEM &val ) {removehelp (root, val); } BinNode<BELEM> *deletemin (BinNode<BELEM> *&); BinNode<BELEM> *find (const BELEM & val) const { return findhelp (root,val); } bool isEmpty ( ) const {return root == NULL } void print ( ) const { if ( root == NULL ) cout < < ‘’BST empty \n ‘’ ; else printhelp (root , 0); } } Trees
BST Class (cont.) template <class BELEM> BinNode<BELEM> *BST<BELEM>::findhelp(BinNode<BELEM> *rt, const BELEM val) const { if (rt == NULL) return NULL ; else if ( val < rtvalue ( ) ) return findhelp (rtleftchild ( ), val ); else if ( val == rtvalue ( ) ) return rt; else return findhelp (rtrightchild ( ), val ); } Trees
BST Class (cont.) template <class BELEM> void BST <BELEM>::inserthelp(BinNode<BELEM> * & rt, const BELEM val) { if (rt == NULL) rt = new BinNode<BELEM> (val, NULL, NULL); else if (val < rtvalue ( ) ) inserthelp (rtleft,val ); else inserthelp (rtright ,val ); } Trees
BST Class (cont.) template <class BELEM> BinNode *BST<BELEM>::deletemin(BinNode<BELEM> *& rt ) { assert (rt ! = NULL); if (rtleft ! = NULL) return deletemin (rtleft ); else { BinNode<BELEM> * temp = rt; rt = rtright; return temp; } } Trees
Array Implementation • General for trees with degree d >= 2 • Many alternatives: • array with pointers to father nodes • array with pointers to children nodes • array with lists of children nodes • binary tree array (good for heaps) Trees
1 A 0 2 B 1 3 C 1 4 D 2 5 E 2 6 F 2 7G 3 Α Β C G D E F a) Pointers to Father Nodes • Easy to find ancestors • Difficult to find children • Minimum space Trees
Α 1A 2 3 2 B 4 5 6 3 C 7 4 D 5 E 6 F 7 G Β C G D E F b) Pointers to Children Nodes • Easy to find children nodes • Difficult to find ancestor nodes Trees
Α Β C G D E F c) Lists of Children Nodes 1 Α 2 3 2 B 4 5 6 3 C 7 4 D 5 E 6 F 7 G • Easy to find children nodes • Difficult to find ancestor nodes Trees
7 7 4 6 4 6 1 2 3 5 1 2 3 5 r: 0 1 2 3 4 5 6 7 4 6 1 2 3 5 d) Binary Tree Array • parent ( r ) = (r-1)/2 if 0 < r < n • leftchild ( r ) = 2r+1 if 2r + 1 < n • rightchild ( r ) = 2r+2 if 2r + 2 < n • leftsibling ( r ) = r-1 if r even &0 < r < n • rightsibling ( r ) = r+1 if r odd & 0 < r+1 < n Trees
max element min element 7 3 6 6 4 4 3 9 Heap • Complete binary tree (not BST) • Min heap: every node has a value >= children • Max heap: every node has a value <= children Trees
Heap Operations • insert new element in heap • build heap from n elements • delete max (min) element from heap • shift-down: move an element from the root to a leaf • Array implementation of page 36 • In the following assume min heap Trees
65 57 57 => => 57 48 25 48 65 48 65 25 25 new element Insertion • Insert last in the array (as leaf) and • shift it to its proper position: swap it with parent elements as long as it has greater value • Complexity O(logn):at most d shift operations in array (d: depth of tree) Trees
R H1 H2 Build Head • Insert n elements in an empty heap • complexity: O(nlogn) • Better bottom-up method: • Assume H1, H2 heaps and shift R down to its proper position (depending on which root from H1, H2 has greater value) • The same (recursively) within H1, H2 Trees
R 7 1 7 H1 H2 R 5 7 5 1 5 6 => => 2 6 3 4 2 6 3 4 2 1 3 4 H1 H2 Example • Starts at d-1 level: the leafs need not be accessed • Shift down elements Trees
Complexity • Up to n/21 elements at d level => 0 moves/elem • Up to n/22 elements at d-1 level => 1 moves/elem … • Up to n/2i elements at level i => i-1 moves/elem total number of moves Trees
57 65 25 => => 57 48 57 48 25 48 25 65 Deletion • The max element is removed • swap with last element in array • delete last element • shift-down root to its proper position • Complexity: O(logn) Trees
Class Heap template <class ELEM> class heap{ private: ΕLEM* Heap ; //pointer to the heap array int size ; // maximum size of the heap int n ; // nnumber of elements now in the heap void siftdown(int) ; // put an element in its proper place public: heap(ELEM*,int, int) ; // constructor int heapsize( ) const ; // return current size of the heap bool isLeaf(int) const ; // TRUE if pos is a leaf position int leftchild(int) const ; // return position for left child int rightchild(int) const ; // return position for right child int parent(int) const ; // return position for parent of pos void insert(const ELEM) ; // insert value into heap ELEM removemax( ) ; // remove maximum value ELEM remove(int) ; // remove value at specified position void buildheap( ) ; // heapify contents of Heap } ; Trees
Class Heap (cont.) template <class ELEM> Heap<ELEM>::heap(ELEM* h, int num , int max) { heap = h; n = num; size = max; buildheap( ); } template <class ELEM> int heap<ELEM>::heapsize( ) const { return n; } template <class ELEM> bool heap<ELEM>::isLeaf(int pos) const { return (pos >= n/2) && (pos < n); } template <class ELEM> intheap<ELEM>::leftchild(int pos) const { assert(pos < n/2); // must be a position with a left child return 2*pos + 1; } Trees
Class Heap (cont.) template <class ELEM> int heap<ELEM>::rightchild(int pos) const { assert(pos < (n-1)/2); // must be a position with a right child return 2*pos + 2; } template <class ELEM> int heap<ELEM>::parent(int pos) const { assert(pos > 0); // pos must have parent return (pos-1)/2; } Trees
Class Heap template <class ELEM> void heap<ELEM>::insert(const ELEM val) { assert(n < size); int curr = n++; Heap[curr] = val; // start at end of heap, then // sift it up until curr’s parent > curr while ((curr != 0) && (key(Heap[curr]) > key(Heap[parent(curr)]))) { swap(Heap[curr], Heap[parent(curr)]); curr = parent(curr); } } Trees
Class Heap (cont.) template <class ELEM> ELEM heap<ELEM>::removemax( ) { assert(n > 0); swap(Heap[0] , Heap[--n]) ; // swap max with last value if (n != 0) // not on last element shiftdown(0); // put new root in correct place return Heap[n]; } Trees
Class Heap (cont.) // remove value at specified position template <class ELEM> ELEM heap<ELEM>::remove(int pos) { assert((pos > 0) && (pos < n)); swap(Heap[pos] , Heap[--n]); // swap with last value if (n != 0) // not on last element shiftdown(pos); // new root in correct place return Heap[n]; } // starts from elements with higher index values (level d-1) template <class ELEM> void heap<ELEM>::buildheap( ) // heapify contents { for (int i = n/2-1; i >= 0; i--) siftdown(i); } Trees
Class Heap (cont.) template <class ELEM> // put elem in proper position void heap<ELEM>::shiftdown(int pos) { assert((pos >= 0) && (pos < n)); while (!isLeaf(pos)) { int j = leftchild(pos); if ((j < (n-1)) && (key(Heap[j]) < key(Heap[j+1]))) j++; // j is index of child with greater value if (key(Heap[pos]) >= key(Heap[j])) return; // Done swap(Heap[pos], Heap[j]); pos = j; // move down } } Trees