// Stephen Bassoli // CSE 124 Section 01 // Lab 7 #include #include #include #include #include "TreeNode.h" template class BinTree { private: TreeNode* root; TreeNode* curr; int size; TreeNode* GetTreeNode(const T& item); // Input: Data value of node // Precond: None // Process: Returns node // Output: Returns node // Postcond: None void FreeNode(TreeNode* t); // Input: Node to be deleted // Precond: None // Process: Deletes node // Output: None // Postcond: None void DeleteTree(TreeNode* t); // Input: Root of tree to be deleted // Precond: None // Process: Deletes tree // Output: None // Postcond: None void IndentBlanks(int num); // Input: Number of level // Precond: None // Process: Formats text of PrintTree method // Output: None // Postcond: None bool SameTree(TreeNode* t1, TreeNode* t2); // Input: Two trees with same root // Precond: None // Process: Compares trees // Output: Returns true if trees are the same // Postcond: None char* PostOrderString(TreeNode* t); char* PostOrderString(TreeNode* t, char* string); // Input: Node to be scanned // Precond: None // Process: Creates string in PostOrder // Output: Returns string in PostOrder // Postcond: None void Simplify(TreeNode* t); // Input: Node to be simplified // Precond: None // Process: Simplifies two duplicate trees // Output: None // Postcond: None void SimplifyZero(TreeNode* t); // Input: Node to be simplified // Precond: None // Process: Simplifies tree that has a zero attached to it // Output: None // Postcond: None void SimplifyOne(TreeNode* t); // Input: Node to be simplified // Precond: None // Process: Simplifies tree that has a one attached to it // Output: None // Postcond: None public: BinTree(void); // Input: None // Precond: None // Process: Constructor // Output: None // Postcond: None BinTree(const BinTree& rhs); // Input: None // Precond: None // Process: Copy Constructor // Output: None // Postcond: None ~BinTree(void); // Input: None // Precond: None // Process: Destructor // Output: None // Postcond: None BinTree& operator= (const BinTree& rhs); // Input: None // Precond: None // Process: Assignment operator // Output: None // Postcond: None void ClearTree(TreeNode* t = NULL); // Input: None (argument is used for recursive use) // Precond: None // Process: Deletes entire tree // Output: None // Postcond: None void Insert(const T& item); // Input: Data of item // Precond: None // Process: Inserts item into the tree // Output: None // Postcond: None void PrintTree(int level = 0); void PrintTree(TreeNode* t, int level = 0); // Input: None (arguments are for recursive use) // Precond: None // Process: Prints the tree // Output: None // Postcond: None void PreOrder(void); void PreOrder(TreeNode* t); // Input: None (arguments are for recursive use) // Precond: None // Process: Prints the tree in PreOrder // Output: None // Postcond: None void InOrder(void); void InOrder(TreeNode* t); // Input: None (arguments are for recursive use) // Precond: None // Process: Prints the tree in InOrder // Output: None // Postcond: None void PostOrder(void); void PostOrder(TreeNode* t); // Input: None (arguments are for recursive use) // Precond: None // Process: Prints the tree in PostOrder // Output: None // Postcond: None void FindDouble(void); void FindDouble(TreeNode* t); // Input: None (arguments are for recursive use) // Precond: None // Process: Finds a node with two of them same children // Output: None // Postcond: None void PostOrderFind(void); void PostOrderFind(TreeNode* t); // Input: None (arguments are for recursive use) // Precond: None // Process: Finds 1s or 0s in the tree then simplifies them // Output: None // Postcond: None }; template BinTree::BinTree(void) { root = curr = NULL; size = 0; } template BinTree::~BinTree(void) { ClearTree(); } template BinTree::BinTree(const BinTree& rhs) { int index, length; char* string; string = new char[100]; strcpy(string, PostOrderString(rhs.root)); length = strlen(string); index = length - 1; for (index ; index >= 0 ; index--) { Insert(string[index]); } delete [] string; } template BinTree& BinTree::operator= (const BinTree& rhs) { int index, length; char* string; string = new char[100]; strcpy(string, PostOrderString(rhs.root)); length = strlen(string); index = length - 1; for (index ; index >= 0 ; index--) { Insert(string[index]); } delete [] string; return *this; } template void BinTree::ClearTree(TreeNode* t) { t = root; DeleteTree(t); t = curr = root = NULL; size = 0; } template TreeNode* BinTree::GetTreeNode(const T& item) { TreeNode* NewTreeNode; NewTreeNode = new TreeNode(item); if (NewTreeNode == NULL) { cerr << "Memory allocation failure!\n"; exit(1); } return NewTreeNode; } template void BinTree::FreeNode(TreeNode *t) { delete t; } template void BinTree::Insert(const T& item) { static bool locked = false; if (size == 0) { root = GetTreeNode(item); curr = root; if (isalnum(item)) locked = true; size++; } else { if (isalnum(item) && curr->LookRight()) { curr->SetRight(GetTreeNode(item)); size++; } else if (isalnum(item) && curr->LookLeft()) { curr->SetLeft(GetTreeNode(item)); size++; } else if (curr->LookRight()) { curr->SetRight(GetTreeNode(item)); curr = curr->Right(); size++; } else if (curr->LookLeft()) { curr->SetLeft(GetTreeNode(item)); curr = curr->Left(); size++; } else { curr = curr->Up(); Insert(item); } } } template void BinTree::DeleteTree(TreeNode* t) { if (t != NULL) { DeleteTree(t->Left()); DeleteTree(t->Right()); FreeNode(t); } } template void BinTree::IndentBlanks(int num) { for (int i = 0 ; i < num ; i++) cout << " "; } template void BinTree::PrintTree(int level) { if (size == 0) { cout << "Empty Tree\n"; return; } TreeNode* t; t = root; if (t != NULL) { PrintTree(t->Right(),level+1); IndentBlanks(6*level); cout << t->Data() << endl; PrintTree(t->Left(), level+1); } } template void BinTree::PrintTree(TreeNode* t, int level) { if (t != NULL) { PrintTree(t->Right(),level+1); IndentBlanks(6*level); cout << t->Data() << endl; PrintTree(t->Left(), level+1); } } template void BinTree::PreOrder(void) { TreeNode* t; t = root; if (t != NULL) { cout << t->Data() << " "; PreOrder(t->Left()); PreOrder(t->Right()); } cout << endl; } template void BinTree::PreOrder(TreeNode* t) { if (t != NULL) { cout << t->Data() << " "; PreOrder(t->Left()); PreOrder(t->Right()); } } template void BinTree::InOrder(void) { TreeNode* t; t = root; if (t != NULL) { InOrder(t->Left()); cout << t->Data() << " "; InOrder(t->Right()); } cout << endl; } template void BinTree::InOrder(TreeNode* t) { if (t != NULL) { if (!(t->LookLeft()&&t->LookRight())) cout << "( "; InOrder(t->Left()); cout << t->Data() << " "; InOrder(t->Right()); if (!(t->LookLeft()&&t->LookRight())) cout << ") "; } } template void BinTree::PostOrder(void) { TreeNode* t; t = root; if (t != NULL) { PostOrder(t->Left()); PostOrder(t->Right()); cout << t->Data() << " "; } cout << endl; } template void BinTree::PostOrder(TreeNode* t) { if (t != NULL) { PostOrder(t->Left()); PostOrder(t->Right()); cout << t->Data() << " "; } } template char* BinTree::PostOrderString(TreeNode *t) { char *string; string = new char[30]; char holder[2]; string[0] = '\0'; if (t != NULL) { strcpy(string,PostOrderString(t->Left(),string)); strcpy(string,PostOrderString(t->Right(),string)); holder[0] = t->Data(); holder[1] = '\0'; strcat(string, holder); } return string; } template char* BinTree::PostOrderString(TreeNode *t, char* string) { char holder[2]; if (t != NULL) { strcpy(string,PostOrderString(t->Left(),string)); strcpy(string,PostOrderString(t->Right(),string)); holder[0] = t->Data(); holder[1] = '\0'; strcat(string, holder); } return string; } template void BinTree::FindDouble(void) { TreeNode *t; t = root; if (!(t->LookLeft() && t->LookRight())) { if (t->WhatLeft() == t->WhatRight()) { if (SameTree(t->Left(),t->Right())) { Simplify(t); } else { FindDouble(t->Left()); FindDouble(t->Right()); } } else if (t != NULL) { FindDouble(t->Left()); FindDouble(t->Right()); } } else if (t->LookLeft() && t->LookRight()) return; } template void BinTree::FindDouble(TreeNode* t) { if (!(t->LookLeft() && t->LookRight())) { if (t->WhatLeft() == t->WhatRight()) { if (SameTree(t->Left(),t->Right())) { Simplify(t); } else { FindDouble(t->Left()); FindDouble(t->Right()); } } else if (t != NULL) { FindDouble(t->Left()); FindDouble(t->Right()); } } else if (t->LookLeft() && t->LookRight()) return; } template bool BinTree::SameTree(TreeNode* t1, TreeNode* t2) { if (strcmp(PostOrderString(t1),PostOrderString(t2)) == 0) return true; else return false; } template void BinTree::Simplify(TreeNode* t) { char op = t->Data(); if (op == '+') { if (isdigit(t->WhatLeft())&&isdigit(t->WhatRight())) return; else { DeleteTree(t->Right()); t->RemoveRight(); t->SetRight(GetTreeNode('2')); t->ChangeData('*'); } } else if (op == '-') { if (t == root) { ClearTree(); } else { DeleteTree(t->Right()); t->RemoveRight(); DeleteTree(t->Left()); t->RemoveLeft(); t->ChangeData('0'); } } else if (op == '/') { DeleteTree(t->Right()); t->RemoveRight(); DeleteTree(t->Left()); t->RemoveLeft(); t->ChangeData('1'); } } template void BinTree::PostOrderFind(void) { TreeNode* t; t = root; if (t != NULL) { PostOrderFind(t->Left()); PostOrderFind(t->Right()); if (t->Data() == '0') SimplifyZero(t); else if (t->Data() == '1') SimplifyOne(t); } } template void BinTree::PostOrderFind(TreeNode* t) { if (t != NULL) { PostOrderFind(t->Left()); PostOrderFind(t->Right()); if (t->Data() == '0') SimplifyZero(t); else if (t->Data() == '1') SimplifyOne(t); } } template void BinTree::SimplifyZero(TreeNode* t) { TreeNode* store; if ((t->WhatUp() == '+')||(t->WhatUp() == '-')) { TreeNode* initial = t; t = t->Up(); store = t->Up(); if (t == root) { if (root->WhatLeft() != '0') { root->RemoveRight(); root = root->Left(); } else if (root->WhatRight() != '0') { root->RemoveLeft(); root = root->Right(); } } else { t->RemoveSelfFromUp(); if (t->Left() == initial) { if (store->Left() == NULL) store->SetLeft(t->Right()); else if (store->Right() == NULL) store->SetRight(t->Right()); } else if (t->Right() == initial) { if (store->Left() == NULL) store->SetLeft(t->Left()); else if (store->Right() == NULL) store->SetRight(t->Left()); } } } else if (t->WhatUp() == '*') { TreeNode* zero; TreeNode* initial = t; t = t->Up(); store = t->Up(); if (t == root) { root = curr = GetTreeNode('0'); size = 1; } else { t->RemoveSelfFromUp(); zero = GetTreeNode('0'); if (store->Right() == NULL) store->SetRight(zero); else if (store->Left() == NULL) store->SetLeft(zero); SimplifyZero(zero); } } } template void BinTree::SimplifyOne(TreeNode* t) { TreeNode* store; if (t->WhatUp() == '*') { TreeNode* initial = t; t = t->Up(); store = t->Up(); if (t == root) { if (root->WhatLeft() != '1') { root->RemoveRight(); root = root->Left(); } else if (root->WhatRight() != '1') { root->RemoveLeft(); root = root->Right(); } } else { t->RemoveSelfFromUp(); if (t->Left() == initial) { if (store->Left() == NULL) store->SetLeft(t->Right()); else if (store->Right() == NULL) store->SetRight(t->Right()); } else if (t->Right() == initial) { if (store->Left() == NULL) store->SetLeft(t->Left()); else if (store->Right() == NULL) store->SetRight(t->Left()); } } } }