Chapter 16 Tree Implementations Chien Chin Chen Department

  • Slides: 51
Download presentation
Chapter 16 Tree Implementations Chien Chin Chen Department of Information Management National Taiwan University

Chapter 16 Tree Implementations Chien Chin Chen Department of Information Management National Taiwan University

The Nodes in a Binary Tree o The first step is to choose a

The Nodes in a Binary Tree o The first step is to choose a data structure to represent nodes. o Since each node must contain both data and “pointers” to the node’s children, it is natural to make each node an object!! n Thus, we will use a C++ class to define the nodes in the tree. o If we place these nodes in an array, the “pointers” in the nodes are array indices. o If the nodes are a part of a linked chain, we use C++ pointers to link them together. 2

An Array-Based Representation (1/3) o An array-based implementation of a tree uses an array

An Array-Based Representation (1/3) o An array-based implementation of a tree uses an array of nodes, so a class of such trees could have the following data members: Tree. Node<Item. Type> tree[MAX_NODES]; // array of tree nodes int root; // index of root int free; // index of free list n root is an index to the tree’s root node within the array tree. o n If the tree is empty, root is -1. As the tree changes due to insertions and removals, its nodes may not be in contiguous elements of the array!! o o You have to establish a collection of available nodes, which is called a free list. free is the index to the first node in the free list. 3

An Array-Based Representation (2/3) o Let’s name our class of nodes Tree. Node. n

An Array-Based Representation (2/3) o Let’s name our class of nodes Tree. Node. n Here, we focus on binary tree!! The class Tree. Node for an array-based implement of the ADT binary tree Template<class Item. Type> class Tree. Node { -1 if a node has private: no left/right child Item. Type item; // data portion int left. Child; // index to left child int right. Child; // index to right child public: Tree. Node(); Tree. Node(const Item. Type &node. Item, int left, int right); . . . }; // end Tree Node 4

An Array-Based Representation (3/3) o free is the index of the first node in

An Array-Based Representation (3/3) o free is the index of the first node in the free list, but the next available node is not necessarily at index free + 1!! o We link the available nodes by making the right. Child member of each node be the index of the next node in the free list. 5

A Link-Based Representation (1/3) o The most common way of implementing a tree is

A Link-Based Representation (1/3) o The most common way of implementing a tree is to use C++ pointers to link the nodes in the tree. Template<class Item. Type> class Binary. Node { private: Tree. Item. Type item; // data portion Binary. Node<Item. Type>* left. Child. Ptr; // pointer to left child Binary. Node<Item. Type>* right. Child. Ptr; // pointer to right child public: Binary. Node(); Binary. Node(const Item. Type& Binary. Node<Item. Type>* an. Item); an. Item, left. Ptr, right. Ptr); 6

A Link-Based Representation (2/3) void set. Item(const Item. Type& an. Item); Item. Type get.

A Link-Based Representation (2/3) void set. Item(const Item. Type& an. Item); Item. Type get. Item() const; bool is. Leaf() const; Binary. Node<Item. Type>* get. Left. Child. Ptr() const; Binary. Node<Item. Type>* get. Right. Child. Ptr() const; void set. Left. Child. Ptr(Binary. Node<Item. Type>* left. Ptr); void set. Right. Child. Ptr(Binary. Node<Item. Type>* right. Ptr); }; // end Binary. Node 7

A Link-Based Representation (3/3) o A class of link-based binary trees will declare one

A Link-Based Representation (3/3) o A class of link-based binary trees will declare one data member: n n o o o A pointer root. Ptr points to the tree’s root. If the tree is empty, root. Ptr contains nullptr. root. Ptr->get. Left. Child. Ptr() points to the root of the left subtree. root. Ptr->get. Right. Child. Ptr() points to the root of the right subtree. If either of these subtrees is empty, the pointer to it would be nullptr. 8

A Link-Based Implementation of the ADT Binary Tree (1/13) o The following is the

A Link-Based Implementation of the ADT Binary Tree (1/13) o The following is the header file of the class Binary. Node. Tree. n n The protected methods – called by the public methods to perform their operations recursively. These methods require pointers (implementation details) as arguments. As such, they should not be public and available to clients of the class. template<class Item. Type> class Binary. Node. Tree : public Binary. Tree. Interface<Item. Type> { private: Binary. Node<Item. Type>* root. Ptr; protected: int get. Height. Helper(Binary. Node<Item. Type>* sub. Tree. Ptr) const; int get. Number. Of. Nodes. Helper(Binary. Node<Item. Type>* sub. Tree. Ptr) const; . . . 9

A Link-Based Implementation of the ADT Binary Tree (2/13) n The public section declares

A Link-Based Implementation of the ADT Binary Tree (2/13) n The public section declares constructors, allowing a client to define binary trees in a variety of circumstances: o o o That is empty From data for its root, which is its only node From data for its root and form its two subtrees public: //------------------------------// Constructor and Destructor Section. //------------------------------Binary. Node. Tree(); Binary. Node. Tree(const Item. Type& root. Item, const Binary. Node. Tree<Item. Type>* left. Tree. Ptr, const Binary. Node. Tree<Item. Type>* right. Tree. Ptr); Binary. Node. Tree(const Binary. Node. Tree<Item. Type>& tree); virtual ~Binary. Node. Tree(); copy constructor 10

A Link-Based Implementation of the ADT Binary Tree (3/13) n For example, the following

A Link-Based Implementation of the ADT Binary Tree (3/13) n For example, the following statements invoke these three constructors: Binary. Node. Tree<string> tree 1; Binary. Node. Tree<string>* tree 2 Ptr = new Binary. Node. Tree<string>(“A”); Binary. Node. Tree<string>* tree 3 Ptr = new Binary. Node. Tree<string >(“B”); Binary. Node. Tree<string>* tree 4 Ptr = new Binary. Node. Tree<string>(“C”, tree 2 Ptr, tree 3 Ptr); n n n tree 1 is an empty binary tree; tree 2 Ptr and tree 3 Ptr each point to binary trees that have only a root node. tree 4 Ptr points to a binary tree whose root contains “C” and has subtrees pointed to by tree 2 Ptr and tree 3 Ptr. 11

A Link-Based Implementation of the ADT Binary Tree (4/13) n The public methods inherited

A Link-Based Implementation of the ADT Binary Tree (4/13) n The public methods inherited from Binary. Tree. Interface. //------------------------------// Public Binary. Tree. Interface Methods Section. //------------------------------bool is. Empty() const; int get. Height() const; int get. Number. Of. Nodes() const; Item. Type get. Root. Data() const throw(Precond. Violated. Excep); void set. Root. Data(const Item. Type& new. Data); bool add(const Item. Type& new. Data); // Adds a node bool remove(const Item. Type& data); // Removes a node void clear(); Item. Type get. Entry(const Item. Type& an. Entry) const throw(Not. Found. Exception); bool contains(const Item. Type& an. Entry) const; 12

A Link-Based Implementation of the ADT Binary Tree (5/13) n The traversal methods inherited

A Link-Based Implementation of the ADT Binary Tree (5/13) n The traversal methods inherited from Binary. Tree. Interface. //------------------------------// Public Traversals Section. //------------------------------void preorder. Traverse(void visit(Item. Type&)) const; void inorder. Traverse(void visit(Item. Type&)) const; void postorder. Traverse(void visit(Item. Type&)) const; //------------------------------// Overloaded Operator Section. //------------------------------Binary. Node. Tree& operator=(const Binary. Node. Tree& right. Hand. Side); }; // end Binary. Node. Tree 13

A Link-Based Implementation of the ADT Binary Tree (6/13) o Here, we examine the

A Link-Based Implementation of the ADT Binary Tree (6/13) o Here, we examine the most significant methods: o The constructors: template<class Item. Type> Binary. Node. Tree<Item. Type>: : Binary. Node. Tree() : root. Ptr(nullptr) { } // end default constructor template<class Item. Type> Binary. Node. Tree<Item. Type>: : Binary. Node. Tree(const Item. Type& root. Item) { root. Ptr = new Binary. Node<Item. Type>(root. Item, nullptr); } // end constructor template<class Item. Type> Binary. Node. Tree<Item. Type>: : Binary. Node. Tree(const Item. Type& root. Item, const Binary. Node. Tree<Item. Type>* left. Tree. Ptr, const Binary. Node. Tree<Item. Type>* right. Tree. Ptr) { root. Ptr = new Binary. Node<Item. Type>(root. Item, copy. Tree(left. Tree. Ptr->root. Ptr), copy. Tree(right. Tree. Ptr->root. Ptr)); } // end constructor 14

A Link-Based Implementation of the ADT Binary Tree (7/13) o The protected method copy.

A Link-Based Implementation of the ADT Binary Tree (7/13) o The protected method copy. Tree uses a recursive preorder traversal to copy each node in the tree. template<class Item. Type> Binary. Node<Item. Type>* Binary. Node. Tree<Item. Type >: : copy. Tree(const Binary. Node<Item. Type>* tree. Ptr) const { Binary. Node<Item. Type>* new. Tree. Ptr = nullptr; // Copy tree nodes during a preorder traversal if (tree. Ptr != nullptr) { // Copy node new. Tree. Ptr = new Binary. Node<Item. Type>(tree. Ptr->get. Item(), nullptr); new. Tree. Ptr->set. Left. Child. Ptr(copy. Tree(tree. Ptr->get. Left. Child. Ptr())); new. Tree. Ptr->set. Right. Child. Ptr( copy. Tree(tree. Ptr->get. Right. Child. Ptr())); } // end if return new. Tree. Ptr; } // end copy. Tree 15

A Link-Based Implementation of the ADT Binary Tree (8/13) o The copy constructor then

A Link-Based Implementation of the ADT Binary Tree (8/13) o The copy constructor then looks like this: template<class Item. Type> Binary. Node. Tree<Item. Type>: : Binary. Node. Tree(const Binary. Node. Tree<Item. Type>& tree) { root. Ptr = copy. Tree(tree. root. Ptr); Erratum!! } // end copy constructor 16

A Link-Based Implementation of the ADT Binary Tree (9/13) o The destructor calls destroy.

A Link-Based Implementation of the ADT Binary Tree (9/13) o The destructor calls destroy. Tree(root. Ptr) to delete each node in the tree in a recursive postorder manner. template<class Item. Type> void Binary. Node. Tree<Item. Type>: : destroy. Tree(Binary. Node<Item. Type>* sub. Tree. Ptr) { if (sub. Tree. Ptr != nullptr) { destroy. Tree (sub. Tree. Ptr->get. Left. Child. Ptr()); destroy. Tree (sub. Tree. Ptr->get. Right. Child. Ptr()); delete sub. Tree. Ptr; } // end if } // end destroy. Tree o The destructor then only needs to make the call destroy. Tree(root. Ptr). template<class Item. Type> Binary. Node. Tree<Item. Type>: : ~Binary. Node. Tree() { destroy. Tree(root. Ptr); } // end destructor 17

A Link-Based Implementation of the ADT Binary Tree (10/13) o Another recursive example: template<class

A Link-Based Implementation of the ADT Binary Tree (10/13) o Another recursive example: template<class Item. Type> int Binary. Node. Tree<Item. Type>: : get. Height. Helper(Binary. Node<Item. Type>* sub. Tree. Ptr) const { if (sub. Tree. Ptr == nullptr) return 0; else return 1 + max(get. Height. Helper(sub. Tree. Ptr->get. Left. Child. Ptr()), get. Height. Helper(sub. Tree. Ptr->get. Right. Child. Ptr())); } // end get. Height. Helper template<class Item. Type> int Binary. Node. Tree<Item. Type>: : get. Height() const { return get. Height. Helper(root. Ptr); } // end get. Height 18

A Link-Based Implementation of the ADT Binary Tree (11/13) o The method Add: n

A Link-Based Implementation of the ADT Binary Tree (11/13) o The method Add: n The specification of the public method add does not indicate where the new node should be in the tree. o We have flexibility in how we define the method. n Let’s add the new node so that the resulting tree is balanced. template<class Item. Type> bool Binary. Node. Tree<Item. Type>: : add(const Item. Type& new. Data) { Binary. Node<Item. Type>* new. Node. Ptr = new Binary. Node<Item. Type>(new. Data); root. Ptr = balanced. Add(root. Ptr, new. Node. Ptr); } return true; // end add 19

A Link-Based Implementation of the ADT Binary Tree (12/13) template<class Item. Type> Binary. Node<Item.

A Link-Based Implementation of the ADT Binary Tree (12/13) template<class Item. Type> Binary. Node<Item. Type>* Binary. Node. Tree<Item. Type>: : balanced. Add( Binary. Node<Item. Type>* sub. Tree. Ptr, Binary. Node<Item. Type>* new. Node. Ptr) { if (sub. Tree. Ptr == nullptr) return new. Node. Ptr; else { Binary. Node<Item. Type>* left. Ptr = sub. Tree. Ptr->get. Left. Child. Ptr(); Binary. Node<Item. Type >* right. Ptr = sub. Tree. Ptr->get. Right. Child. Ptr(); if (get. Height. Helper(left. Ptr) > get. Height. Helper(right. Ptr)) { right. Ptr = balanced. Add(right. Ptr, new. Node. Ptr); sub. Tree. Ptr->set. Right. Child. Ptr(right. Ptr); } else { left. Ptr = balanced. Add(left. Ptr, new. Node. Ptr); sub. Tree. Ptr->set. Left. Child. Ptr(left. Ptr); } return sub. Tree. Ptr; } } 20

A Link-Based Implementation of the ADT Binary Tree (13/13) o The traversals: n Since

A Link-Based Implementation of the ADT Binary Tree (13/13) o The traversals: n Since the traversal are recursive (using pointers – implementation details), the public traversal methods each calls a protected method that performs the actual recursion. template<class Item. Type> void Binary. Node. Tree<Item. Type>: : inorder( void visit(Item. Type&), Binary. Node<Item. Type>* tree. Ptr) const { if (tree. Ptr != nullptr) function as a parameter { inorder(visit, tree. Ptr->get. Left. Child. Ptr()); Item. Type the. Item = tree. Ptr->get. Item(); visit(the. Item); inorder(visit, tree. Ptr->get. Right. Child. Ptr()); } template<class Item. Type> void Binary. Node. Tree<Item. Type>: : inorder. Traverse(void visit(Item. Type&)) const { inorder(visit, root. Ptr); } 21

A Link-Based Implementation of the ADT Binary Search Tree (1/20) o Since a binary

A Link-Based Implementation of the ADT Binary Search Tree (1/20) o Since a binary search tree is a binary tree, its implementation can use the same node objects as for a binary-tree implementation. n We will use the class Binary. Node. n We assume that the data items in the binary search tree are unique!! o The recursive search algorithm is the basis of the insertion, removal, and retrieval operations on a binary search tree. 22

A Link-Based Implementation of the ADT Binary Search Tree (2/20) o Adding a new

A Link-Based Implementation of the ADT Binary Search Tree (2/20) o Adding a new entry: n You insert a new entry into a binary search tree in the same place that the search algorithm would look for it!! n Because searching for an entry that is not in the binary search tree always ends at an empty subtree … YOU ALWAYS INSERT A NEW ITEM AS A NEW LEAF!! n Adding a leaf requires only a change of the appropriate pointer in the parent. 23

A Link-Based Implementation of the ADT Binary Search Tree (3/20) template<class Item. Type> int

A Link-Based Implementation of the ADT Binary Search Tree (3/20) template<class Item. Type> int Binary. Search. Tree<Item. Type>: : add(const Item. Type& new. Data) { Binary. Node<Item. Type>* new. Node. Ptr = new Binary. Node<Item. Type>(new. Data); root. Ptr = insert. Inorder(root. Ptr, new. Node. Ptr); } return true; // end add // pseudocode of insert. Inorder(sub. Tree. Ptr: : Binary. Node. Pointer, new. Node. Ptr: Binary. Node. Pointer): Binary. Node. Pointer if (sub. Tree. Ptr is nulptr) return new. Node. Ptr else if (sub. Tree. Ptr->get. Item() > new. Node. Ptr->get. Item()) { temp. Ptr = insert. Inorder(sub. Tree. Ptr->get. Left. Child. Ptr(), new. Node. Ptr) sub. Tree. Ptr->set. Left. Child. Ptr(temp. Ptr) } else { temp. Ptr = insert. Inorder(sub. Tree. Ptr->get. Right. Child. Ptr(), new. Node. Ptr) sub. Tree. Ptr->set. Right. Child. Ptr(temp. Ptr ) } return sub. Tree. Ptr 24

A Link-Based Implementation of the ADT Binary Search Tree (4/20) o Removing an entry:

A Link-Based Implementation of the ADT Binary Search Tree (4/20) o Removing an entry: n Is more complicated than adding. n First, you use the search algorithm to locate the specified item. o If it is found, you must remove it from the tree. n Assuming that remove. Value locates the target in a particular node N. 25

A Link-Based Implementation of the ADT Binary Search Tree (5/20) remove. Value(sub. Tree. Ptr:

A Link-Based Implementation of the ADT Binary Search Tree (5/20) remove. Value(sub. Tree. Ptr: Binary. Node. Pointer, target: Item. Type, success: Boolean&): Binary. Node. Pointer if(sub. Tree. Ptr == nullptr) { success = false return nullptr } else if (sub. Tree. Ptr->get. Item() == target) { sub. Tree. Ptr = remove. Node(sub. Tree. Ptr) success = true return sub. Tree. Ptr } else if (sub. Tree. Ptr->get. Item() > target) { temp. Ptr = remove. Value(sub. Tree. Ptr->get. Left. Child. Ptr(), target, success) sub. Tree. Ptr->set. Left. Child. Ptr(temp. Ptr) return sub. Tree. Ptr } else { temp. Ptr = remove. Value(sub. Tree. Ptr->get. Right. Child. Ptr(), target, success) sub. Tree. Ptr->set. Right. Child. Ptr(temp. Ptr ) return sub. Tree. Ptr } 26

A Link-Based Implementation of the ADT Binary Search Tree (6/20) o The essential task

A Link-Based Implementation of the ADT Binary Search Tree (6/20) o The essential task is to remove the target N from the tree (remove. Node). n There are three cases to consider: o N is a leaf o N has only one child o N has two children n Case 1 is the easiest. You need only set the pointer in its parent to nullptr. 27

A Link-Based Implementation of the ADT Binary Search Tree (7/20) o Case 2 is

A Link-Based Implementation of the ADT Binary Search Tree (7/20) o Case 2 is a bit more involved. o If N has only one child: n N has only a left child n N has only a right child o The two possibilities are symmetrical, so we illustrate the solution for a left child. 28

A Link-Based Implementation of the ADT Binary Search Tree (8/20) o Let L take

A Link-Based Implementation of the ADT Binary Search Tree (8/20) o Let L take the place of N as one of P’s children… Yes, the binary search tree property is preserved!! o Does this adoption preserve the binary search tree property? 29

A Link-Based Implementation of the ADT Binary Search Tree (9/20) o Case 3 is

A Link-Based Implementation of the ADT Binary Search Tree (9/20) o Case 3 is the most difficult case. o N’s parent has room for only one N’s children as a replacement for N!! 30

A Link-Based Implementation of the ADT Binary Search Tree (10/20) o In fact, you

A Link-Based Implementation of the ADT Binary Search Tree (10/20) o In fact, you can find another node that is easier to delete and delete it instead of N. n This strategy may sound like cheating… n But remember that the client expects only a certain entry to be removed from the ADT. n It has no right, because of the WALL between the program and the ADT implementation, to expect a particular node in the tree to be deleted. 31

A Link-Based Implementation of the ADT Binary Search Tree (11/20) o Removing strategy: 1.

A Link-Based Implementation of the ADT Binary Search Tree (11/20) o Removing strategy: 1. Locate another node M that is easier to remove from the tree than the node N. 2. Copy the item that is in M to N, thus effectively removing from the tree the item originally in N. 3. Remove the node M from the tree. o But … what kind of node M is easier to remove? ? 32

A Link-Based Implementation of the ADT Binary Search Tree (12/20) o M should have

A Link-Based Implementation of the ADT Binary Search Tree (12/20) o M should have a single child or no children. n After replacing N by M, you must also preserve the tree’s status as a binary search tree!! 33

A Link-Based Implementation of the ADT Binary Search Tree (13/20) o There are two

A Link-Based Implementation of the ADT Binary Search Tree (13/20) o There are two suitable possibilities for the replacement. n You can copy into N the item that is immediately before/after N in the sorted order. n Suppose that we decide to use the node y whose entry comes immediately after N’s entry x. o This entry is called x’s inorder successor. 34

A Link-Based Implementation of the ADT Binary Search Tree (14/20) o How can you

A Link-Based Implementation of the ADT Binary Search Tree (14/20) o How can you locate this node? o Because N has two children, the inorder successor is in the leftmost node of N’s right subtree. n n You follow N’s right-child pointer to its right child C (must be present). Then, you descend the tree rooted at C by taking left branches at each node … until you encounter a node S with no left child. Copy the item in S into N. REMOVE S!! o Because S has no left child you can remove S from the tree as one of the two easy cases. 35

A Link-Based Implementation of the ADT Binary Search Tree (15/20) o Pseudocode of remove.

A Link-Based Implementation of the ADT Binary Search Tree (15/20) o Pseudocode of remove. Node(N: : Binary. Node) Draf if (N is a leaf) Remove N from the tree else if (N has only one child C) { if (N was a left child of its parent P) Make C the left child of P else Make C the right child of P } else { Find S, the node that contains N’s inorder successor Copy the item from node S into node N Remove S from the tree by using the previous technique for a leaf or a node with one child } t 36

A Link-Based Implementation of the ADT Binary Search Tree (16/20) remove. Node(node. Ptr: :

A Link-Based Implementation of the ADT Binary Search Tree (16/20) remove. Node(node. Ptr: : Binary. Node. Pointer): Binary. Node. Pointer if (N is a leaf) { delete node. Ptr = nullptr return node. Ptr } else if (N has only one child C) { if (C is the left child) node. To. Connect. Ptr = node. Ptr->get. Left. Child. Ptr() else node. To. Connect. Ptr = node. Ptr-> get. Right. Child. Ptr() delete node. Ptr = nullptr return node. To. Connect. Ptr Erratum!! } 37

A Link-Based Implementation of the ADT Binary Search Tree (17/20) else { temp. Ptr

A Link-Based Implementation of the ADT Binary Search Tree (17/20) else { temp. Ptr = remove. Leftmost. Node(node. Ptr->get. Right. Child. Ptr(), new. Node. Value) node. Ptr->set. Right. Child. Ptr(temp. Ptr) node. Ptr->set. Item(new. Node. Value) return node. Ptr } 38

A Link-Based Implementation of the ADT Binary Search Tree (18/20) remove. Leftmost. Node(node. Ptr:

A Link-Based Implementation of the ADT Binary Search Tree (18/20) remove. Leftmost. Node(node. Ptr: : Binary. Node. Pointer, inorder. Successor: Item. Type&): Binary. Node. Pointer if (node. Ptr->get. Left. Child. Ptr() == nullptr) { inorder. Successor = node. Ptr->get. Item() return remove. Node(node. Ptr) } else { temp. Ptr = remove. Leftmost. Node(node. Ptr->get. Left. Child. Ptr (), inorder. Successsor) node. Ptr->set. Left. Child. Ptr(temp. Ptr) return node. Ptr } Erratum!! 39

A Link-Based Implementation of the ADT Binary Search Tree (19/20) o The public method

A Link-Based Implementation of the ADT Binary Search Tree (19/20) o The public method remove: remove (target: Item. Type): boolean success = false root. Ptr = remove. Value(root. Ptr, target, success) return success 40

A Link-Based Implementation of the ADT Binary Search Tree (20/20) o Retrieving an entry

A Link-Based Implementation of the ADT Binary Search Tree (20/20) o Retrieving an entry – get. Entry: n n Call find. Node to recursively checks whether the desired target is in a binary search tree. It checks the return value, and returns the desired target or throws an exception find. Node (sub. Tree. Ptr: Binary. Node. Pointer, target: item. Type): Binary. Node. Pointer if(sub. Tree. Ptr == null. Ptr) return nullptr else if (sub. Tree. Ptr->get. Item()== target) return sub. Tree. Ptr; else if (sub. Tree. Ptr->get. Item() >target) return find. Node(sub. Tree. Ptr->get. Left. Child. Ptr(), target) else return find. Node(sub. Tree. Ptr-> get. Right. Child. Ptr(), target) 41

Saving a Binary Search in a File (1/6) o Saving a binary search tree

Saving a Binary Search in a File (1/6) o Saving a binary search tree and then restoring it to its original shape: n Uses preorder traversal to save the tree to a file. 60 60 20 10 70 save 40 30 20 restore 10 50 70 40 30 50 Preorder: 60 20 10 40 30 50 70 42

Saving a Binary Search in a File (2/6) o Saving a binary search tree

Saving a Binary Search in a File (2/6) o Saving a binary search tree and then restoring it to a balanced shape: n Uses inorder traversal to save the tree to a file. o To make the data sorted. n To restore, need the number of nodes in the tree. o Can determine the middle item and, in turn, the number of nodes in the left and right subtrees of the tree’s root. 43

Saving a Binary Search in a File (3/6) o Restoring a full binary search

Saving a Binary Search in a File (3/6) o Restoring a full binary search tree: n You can use the following recursive algorithm to create a full binary search tree with n nodes (provided you either know or can determine n beforehand). read. Full. Tree (tree. Ptr: Binary. Node. Pointer, n: integer): Binary. Node. Pointer if (n > 0) { tree. Ptr = pointer to new node with nullptr as its child pointers // Construct the left subtree left. Ptr = read. Full. Tree(tree. Ptr->get. Left. Child. Ptr(), n / 2) tree. Ptr->set. Left. Child. Ptr(left. Ptr) // Get the root. Item = next item from file tree. Ptr->set. Item(root. Item) Erratum!! // Construct the right subtree right. Ptr = read. Full. Tree(tree. Ptr->get. Right. Child. Ptr(), n / 2) tree. Ptr->set. Right. Child. Ptr(right. Ptr) return tree. Ptr } else return nullptr 44

Saving a Binary Search in a File (4/6) o If the tree to be

Saving a Binary Search in a File (4/6) o If the tree to be restored is not full: n The first thing that comes to mind is that the resorted tree should be complete. n But … you care only abut minimizing the height of the restored tree. It does not matter where the nodes on the last level go. 45

Saving a Binary Search in a File (5/6) o The method read. Full. Tree

Saving a Binary Search in a File (5/6) o The method read. Full. Tree is correct even if the tree is not full!! o However, you have to be a bit careful when computing the sizes of the left and right subtrees of the tree’s root. n n If n is odd, both subtrees are of size n/2. If n is even, you have to deal with the fact that one subtree will have one more node than the other. n In this case, we put the extra node in the left subtree. 46

Saving a Binary Search in a File (6/6) read. Tree(tree. Ptr: Binary. Node. Pointer,

Saving a Binary Search in a File (6/6) read. Tree(tree. Ptr: Binary. Node. Pointer, n: integer): Binary. Node. Pointer if (n > 0) { tree. Ptr = pointer to new node with nullptr as its child pointers // Construct the left subtree left. Ptr = read. Tree(tree. Ptr->get. Left. Child. Ptr(), n / 2) tree. Ptr->set. Left. Child. Ptr(left. Ptr) // Get the root. Item = next item from file tree. Ptr->set. Item(root. Item) // Construct the right subtree right. Ptr = read. Tree(tree. Ptr->get. Right. Child. Ptr(), (n - 1) / 2) tree. Ptr->set. Right. Child. Ptr(right. Ptr) return tree. Ptr Erratum!! } else return nullptr 47

Treesort (1/2) o Treesort Uses the ADT binary search tree to sort an array

Treesort (1/2) o Treesort Uses the ADT binary search tree to sort an array of integers into ascending order. tree. Sort(an. Array: array, n: integer) Insert an. Array’s entries into a binary search tree bst Traverse bst in inorder. As you visit bst’s nodes, copy their data items into successive locations of an. Array n 48

Treesort (2/2) o Analysis: n Insertion: o Each insertion into a binary search tree

Treesort (2/2) o Analysis: n Insertion: o Each insertion into a binary search tree requires O(logn) operations in the average case. o And O(n) operations in the worst case. o Thus, n-node insertions require O(nlogn) operations in average case, and O(n 2) operations in the worst case. n The inroder traversal: o O(n) in all cases. n Sum up: o Average case: O(nlogn) o Worst case: O(n 2) 49

General Trees (1/2) o Each node can have an arbitrary number of children. o

General Trees (1/2) o Each node can have an arbitrary number of children. o A binary tree can represent a general tree. n Each node has two pointers: o The left pointer points to the node’s oldest (first) child. o The right pointer points to the node’s next sibling. 50

General Trees (2/2) o An n-ary tree is a general tree whose nodes can

General Trees (2/2) o An n-ary tree is a general tree whose nodes can have no more than n children each. o In implementation, each node points directly to its children. 51