Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
Jarred FletesCS330
November 19, 2016Homework 5
1. ( 10 points ) The following is a binary tree.
For each of the traversal algorithms we have discussed ( preorder, inorder, and postorder ), list the sequence in which nodes would be processed.
Preorder: {A, B, D, H, E, I, N, O, J, C, F, K, G, L, M};
inorder: {H, D, B, N I, O, E, J, A, K, F, C, L, G, M};
postorder: {H, D, N, O, I, J, E, B, K, F, L, M, G, C, A};
2. ( 20 points ) Make use of the BST implementation given in /pool/u/class/cs330/tree and some of its member functions like deleteMin() and retrieve() to implement a delete() member function of the BST class. The function searches the BST to find the node that contains the input key and then deletes the record if the node exists. Test your function using a routine similar to main2.cpp given in the directory. You should test the three cases that we have discussed in class:deleting a node that has no child,deleting a node that has one child, anddeleting a node that has two children.
I will delete the 4 which has no child.I will delete the 55 which has 1 child.I will delete the 66 which has 2 children.
//util.cpp : utility functions for manipulating binary tree#include "bst.cpp"#include "item.h"#include "util.h"
using namespace std;
//contruct a binary tree from an array recursivelybinTree<ITEM> *array2tree(ITEM a[], int i, int size){ binTree<ITEM> *dummy = new binTree<ITEM>; if (i>=size) return dummy; binTree <ITEM> *temp = new binTree<ITEM>; //This merges two subtree to one with a[i] residing in root temp->mergeTree(a[i], array2tree(a, 2*i+1, size), array2tree(a, 2*i+2, size)); return temp;}
void inOrder( btpitem bp ){ if ( !bp->isEmpty() ) { inOrder( bp->leftSub() ); ITEM data = bp->getData();#ifdef main0 cout << bp->getData().value << ' ';#else cout << "(" << data.key << " , " << data.value << " ), ";#endif inOrder( bp->rightSub() ); }}
void postOrder( btpitem bp ){ if ( !bp->isEmpty() ) { postOrder( bp->leftSub() ); postOrder( bp->rightSub() ); ITEM data = bp->getData();#ifdef main0 cout << bp->getData().value << ' ';#else cout << "(" << data.key << " , " << data.value << " ), ";#endif }}
void preOrder ( btpitem bp ) { if ( !bp->isEmpty() ) { ITEM data = bp->getData();# ifdef main0 cout << bp->getData().value << ' ' ;
# else cout << "(" << data.key << " , " << data.value << " ), " ; #endif preOrder( bp->leftSub() ); preOrder( bp->rightSub() ); }
}//convert an integer to a stringstring int_to_string(int n){ ostringstream outstr; outstr << n; return outstr.str();}
//bst.cpp/* A sample implementation of Binary Search Tree. The class is a subclass of binTree ( binary tree )*/
#ifndef BST_CPP#define BST_CPP
#include <iostream>#include <assert.h>#include <stdio.h>#include <stdlib.h>
using namespace std;
//defines the interface of binary treetemplate <class T>class binTree{public: binTree();
virtual bool isEmpty() const; virtual T getData() const; virtual void insert(const T &a); virtual binTree *leftSub(); // points to root of left subtree virtual binTree *rightSub(); virtual void makeLeft(binTree *t1); // this->left==t1, (post condition) virtual void makeRight(binTree *t1);// virtual void print(); //should not define print() here because data type T is undefined at the moment virtual void mergeTree(T a, binTree *tlp, binTree *trp);protected: bool emptyTree; T data; binTree *leftTree; binTree *rightTree;};
template <class T>binTree<T>::binTree(){ emptyTree=true; leftTree=NULL; rightTree=NULL;}
template <class T>bool binTree<T>::isEmpty() const{ return emptyTree;}
template <class T>T binTree<T>::getData() const{ assert(!isEmpty());// is tree empty? return data;}
template <class T>void binTree<T>::insert(const T &a){ data = a; if (isEmpty()) { emptyTree=false; leftTree = new binTree; rightTree = new binTree;
}}
template <class T>binTree<T>* binTree<T>::leftSub(){ //assert (!isEmpty());//is tree empty? return leftTree;}
template <class T>binTree<T>* binTree<T>::rightSub(){ // assert( !isEmpty());//is tree empty? return rightTree;}
template <class T>void binTree<T>::makeLeft(binTree *t1){ assert (!isEmpty());//is tree empty?// assert (leftTree->isEmpty()); //make sure left tree pointer is NULL leftTree = t1;}
template <class T>void binTree<T>::makeRight(binTree *t1){ assert (!isEmpty());//is tree empty? assert (rightTree->isEmpty()); //make sure left tree pointer is NULL rightTree = t1;}
template <class T>void binTree<T>::mergeTree(T a, binTree *tlp, binTree *trp){ data =a; leftTree=tlp; rightTree=trp; emptyTree=false;}
/* Binary search tree ( BST ) interface. BST class inherits everything
from binTree class. Here, insert() function has to insert an item at proper position.*/template <class T>class BST : public binTree<T> {public: virtual void insert( const T &a ); //insert item into proper position virtual binTree<T> *retrieve( const T &a, bool &found ); //retrieve item from a nod virtual T deleteMin(); //delete the node containing minimum key virtual bool update( const T &a ); virtual void deleteNode( const T &a );};
template <class T>void BST<T>::insert( const T &a ){ if ( binTree<T>::emptyTree ) { binTree<T>::emptyTree = false; binTree<T>::leftTree = new BST; binTree<T>::rightTree = new BST; binTree<T>::data = a; } else if ( a.key == binTree<T>::data.key ) //find the proper position until reaching a leaf binTree<T>::data = a; else if ( a.key < binTree<T>::data.key ) binTree<T>::leftTree->insert( a ); else binTree<T>::rightTree->insert( a );}
//returns the subtree whose root contains the datatemplate <class T>binTree<T> *BST<T>::retrieve( const T &a, bool &found ){ binTree<T> *bp; bp = this; found = true; while ( !bp->isEmpty() ) { if ( a.key == bp->getData().key ) return bp; else if ( a.key < bp->getData().key ) bp = bp->leftSub(); else bp = bp->rightSub(); } //while found = false;
return bp; //not exists}
template <class T>bool BST<T>::update( const T &a ){ bool found; retrieve(a,found); if(found) insert(a); return found;}
//returns the minimum itemtemplate <class T>T BST<T>::deleteMin(){ binTree<T> *bp, *bpp, *temp; assert( !binTree<T>::isEmpty() ); bp = this; bpp = NULL; T min; min = bp->getData(); if ( bp->leftSub()->isEmpty() ) { //root is min min = bp->getData(); temp = bp; bp = bp->rightSub(); //pointing to right subtree which //becomes new root binTree<T>::emptyTree = bp->isEmpty(); binTree<T>::leftTree = bp->leftSub(); binTree<T>::rightTree = bp->rightSub(); if ( !binTree<T>::isEmpty() ) { temp = bp; //originally missed statement, first found by Polina binTree<T>::data = bp->getData(); } } else { //min is at left subtree while ( !bp->leftSub()->isEmpty() ) { bpp = bp; //remember parent bp = bp->leftSub(); //keep going left } min = bp->getData(); bpp->makeLeft( bp->rightSub() ); temp = bp; } if ( temp != NULL ) delete temp;
return( min );} //deleteMin()
template<class T>void BST<T>::deleteNode( const T &a ){ bool found; binTree<T> *bp, *bpp, *temp; BST<T> *teemp = NULL; assert(!binTree<T>::isEmpty()); bp = this; bpp = NULL; temp = NULL; found = false; while (!bp->isEmpty()) { if(a.key == bp->getData().key ) { found = true; break; } else if(a.key < bp->getData().key) { bpp = bp; bp = bp->leftSub(); }else { bpp = bp; bp = bp->rightSub(); } } if(found) { if(bpp->leftSub()->isEmpty() && bp->rightSub()->isEmpty()){ if(bpp == NULL) { binTree<T>::emptyTree = true; binTree<T>::data = T(); } else if(bpp->leftSub() == bp) bpp->makeLeft(bp->leftSub()); else if(bpp->rightSub() == bp) bpp->makeRight(bp->rightSub()); return; } else if(bp->leftSub()->isEmpty() || bp->rightSub()->isEmpty()) { if(bpp == NULL) { if(bp->rightSub()->isEmpty()) bp->rightSub()->makeLeft(bp->leftSub()); else bp->leftSub()->makeRight(bp->rightSub());
} else if(bpp->rightSub() == bp ){ if(bp->leftSub()->isEmpty()) bpp->makeRight(bp->rightSub()); else bpp->makeRight(bp->leftSub()); } else if(bpp->leftSub()==bp) { if(bp->leftSub()->isEmpty()) bpp->makeLeft(bp->rightSub()); else bpp->makeLeft(bp->leftSub()); } return; } else { temp = bp->rightSub(); while (!temp->leftSub()->isEmpty()) temp = temp->leftSub(); bp->leftSub()->makeRight(temp); return; }}return;}
#endif
//main2.cpp#include "bst.cpp"#include "item.h"#include "util.cpp"
using namespace std;
int main(){ int x; cout <<"Enter an array of integers, -99 to terminate"<<endl; cin >> x; ITEM a; a.key = x; a.value = int_to_string(x); BST<ITEM> bst1;
while(x != -99) { bst1.insert(a); cin >> x; a.key = x; a.value = int_to_string(x); } cout << "\n In order traversal of tree: \n"; inOrder(&bst1); cout << endl; cout << "\nPost order traversal of tree: \n"; postOrder(&bst1); cout << endl; cout << "\nPre order traversal of tree: \n"; preOrder(&bst1); cout << endl;
cout <<"\nEnter a key to delete: "; cin >> x; a.key = x; bst1.deleteNode(a);
cout << "\nIn order traversal of tree: \n"; inOrder(&bst1); cout << endl; cout << "\nPost order traversal of tree: \n"; postOrder(&bst1); cout << endl; cout <<"\nPre order traversal of tree: \n"; preOrder(&bst1); cout << endl;
return 0; }
3. ( 10 points ) Draw a sequence of diagrams along with brief explanations to show how you construct a Red/Black tree for the following sequence of integer keys: 2, 4, 5, 7, 8, 12, 6, 20, 1 i.e., We create the tree by first inserting 2, followed by 4, and then 5, and so on. Draw the final tree. (It would be nice if you could use red color to draw red nodes and black color to draw black nodes in your diagrams.)
We first insert 2 and 4. 2 is the black root and 4 becomes the node to the right of 2.
When we insert the 5. The 4 becomes the root with the lesser value 2 on the left and the greater value 5 on the right.
When we insert the 7 it moves from being greater than 4 the greater than five to the right node of 5. 7 becomes a red node.
When the 8 is inserted it is greater than 4, and greater then 7. However, at this point it is better to make the 7 the black node and insert the 8 to the right of 7 and the 5 to the left and both become red nodes.
When the 12 is inserted it is greater than 4, greater than 7 and then greater than 8. 12 becomes red and 8 black.
When the 6 is inserted it is greater than 4, less than 7 and greater than 5. It will be a red node.
When the 20 is inserted it is greater than 4, greater than 7. Then the 12 becomes the parent node and is black and the 20 goes as it’s right child with the 8 on the left, both red.
When the 1 is inserted it is less than 4 less than 2. It is the left child of 2 and is red.
I give myself a 40 on this assignment. I completed all parts and I believe it looks neat.