Add iterative version of binary tree traversal and enum to switch algo
This commit is contained in:
		
							parent
							
								
									011236f238
								
							
						
					
					
						commit
						65996765d1
					
				| @ -60,15 +60,15 @@ To run the tests: | ||||
| ** Stacks and Queues [0/2] | ||||
| - [ ] Stack Min (CTCI: 3.1) | ||||
| - [ ] Sort Stack (CTCI: 3.5) | ||||
| ** Trees and Graphs [4/9] | ||||
| ** Trees and Graphs [7/9] | ||||
| - [X] Implement binary tree object | ||||
|   - Insert breadth first | ||||
| - [X] Recursive Pre-order traversal | ||||
| - [X] Recursive In-order traversal | ||||
| - [X] Recursive Post-order traversal | ||||
| - [ ] Non-Recursive Pre-order traversal | ||||
| - [ ] Non-Recursive In-order traversal | ||||
| - [ ] Non-Recursive Post-order traversal | ||||
| - [X] Non-Recursive Pre-order traversal | ||||
| - [X] Non-Recursive In-order traversal | ||||
| - [X] Non-Recursive Post-order traversal | ||||
| - [ ] Min Heap | ||||
| - [ ] Binary Search | ||||
| ** C/C++ [2/5] | ||||
|  | ||||
| @ -1,6 +1,12 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <queue> | ||||
| #include <stack> | ||||
| 
 | ||||
| typedef enum AlgoVariant_E{ | ||||
|   Recursive, | ||||
|   Iter, | ||||
| }AlgoVariant; | ||||
| 
 | ||||
| template <class T> | ||||
| class DopeBinTreeNode{ | ||||
| @ -23,6 +29,9 @@ class DopeBinTree{ | ||||
|   T* RecPreOrderTraversal(DopeBinTreeNode<T>* node, T* out); | ||||
|   T* RecInOrderTraversal(DopeBinTreeNode<T>* node, T* out); | ||||
|   T* RecPostOrderTraversal(DopeBinTreeNode<T>* node, T* out); | ||||
|   void IterPreOrderTraversal(DopeBinTreeNode<T>* node, T* out); | ||||
|   void IterInOrderTraversal(DopeBinTreeNode<T>* node, T* out); | ||||
|   void IterPostOrderTraversal(DopeBinTreeNode<T>* node, T* out); | ||||
| public: | ||||
|   DopeBinTree(T data); | ||||
|   DopeBinTree(); | ||||
| @ -30,9 +39,9 @@ public: | ||||
|   void insert(T data); | ||||
|   bool isEmpty(); | ||||
|   DopeBinTreeNode<T>* getRoot(){return root;} | ||||
|   void RecPreOrderTraversalArray(T* array); | ||||
|   void RecInOrderTraversalArray(T* array); | ||||
|   void RecPostOrderTraversalArray(T* array); | ||||
|   void PreOrderTraversal2Array(T* array, AlgoVariant variant); | ||||
|   void InOrderTraversal2Array(T* array, AlgoVariant variant); | ||||
|   void PostOrderTraversal2Array(T* array, AlgoVariant variant); | ||||
| }; | ||||
| 
 | ||||
| // Implementations ___________________________________________________
 | ||||
| @ -147,26 +156,145 @@ T* DopeBinTree<T>::RecPostOrderTraversal(DopeBinTreeNode<T>* node, T* out){ | ||||
| } | ||||
| 
 | ||||
| template <class T> | ||||
| void DopeBinTree<T>::RecPreOrderTraversalArray(T* array){ | ||||
| void DopeBinTree<T>::IterPreOrderTraversal(DopeBinTreeNode<T>* node, T* out){ | ||||
|   std::stack<DopeBinTreeNode<T>*> s = {}; | ||||
|   s.push(node); | ||||
| 
 | ||||
|   while(s.empty() == false){ | ||||
|     node = s.top(); | ||||
|     s.pop(); | ||||
|     *out = node->GetData(); | ||||
|     out++; | ||||
|     if(node->GetRight()){ | ||||
|       s.push(node->GetRight()); | ||||
|     } | ||||
|     if(node->GetLeft()){ | ||||
|       s.push(node->GetLeft()); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| template <class T> | ||||
| void DopeBinTree<T>::IterInOrderTraversal(DopeBinTreeNode<T>* node, T* out){ | ||||
|   std::stack<DopeBinTreeNode<T>*> s = {}; | ||||
| 
 | ||||
|   while (!s.empty() || node){ | ||||
|     while(node != nullptr){ | ||||
|       s.push(node); | ||||
|       node = node->GetLeft(); | ||||
|     } | ||||
|     node = s.top(); | ||||
|     s.pop(); | ||||
|     *out = node->GetData(); | ||||
|     out++; | ||||
|     node = node->GetRight(); | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| template <class T> | ||||
| void DopeBinTree<T>::IterPostOrderTraversal(DopeBinTreeNode<T>* node, T* out){ | ||||
|   std::stack<DopeBinTreeNode<T>*> s_tmp = {}; | ||||
|   std::stack<DopeBinTreeNode<T>*> s_fin = {}; | ||||
| 
 | ||||
|   s_tmp.push(node); | ||||
|   while(!s_tmp.empty()){ | ||||
|     node = s_tmp.top(); | ||||
|     s_tmp.pop(); | ||||
|     s_fin.push(node); | ||||
| 
 | ||||
|     if(node->GetLeft()){ | ||||
|       s_tmp.push(node->GetLeft()); | ||||
|     } | ||||
|     if(node->GetRight()){ | ||||
|       s_tmp.push(node->GetRight()); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   while(!s_fin.empty()){ | ||||
|     node = s_fin.top(); | ||||
|     s_fin.pop(); | ||||
|     *out = node->GetData(); | ||||
|     out++; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  \brief PreOrderTraversal2Array | ||||
|  * | ||||
|  *  Binary tree traversal that visits the root node, then the left | ||||
|  *  sub-tree, and then the right-subtree. | ||||
|  * | ||||
|  *  \param The output array | ||||
|  *  \param The algorithm variant | ||||
|  *  \return return type | ||||
|  */ | ||||
| template <class T> | ||||
| void DopeBinTree<T>::PreOrderTraversal2Array(T* array, AlgoVariant variant){ | ||||
|   int index = 0; | ||||
|   DopeBinTreeNode<T>* node = root; | ||||
| 
 | ||||
|   switch(variant){ | ||||
|   case AlgoVariant::Recursive: | ||||
|     RecPreOrderTraversal(node, &array[index]); | ||||
| 
 | ||||
|     return; | ||||
|   case AlgoVariant::Iter: | ||||
|     IterPreOrderTraversal(node, &array[index]); | ||||
|     return; | ||||
|   default: | ||||
|     return; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  \brief InOrderTraversal2Array | ||||
|  * | ||||
|  *  Binary tree traversal that traverses the left sub-tree, then | ||||
|  *  visits the root node, then the right-subtree. | ||||
|  * | ||||
|  *  \param The output array | ||||
|  *  \param The algorithm variant | ||||
|  *  \return return type | ||||
|  */ | ||||
| template <class T> | ||||
| void DopeBinTree<T>::RecInOrderTraversalArray(T* array){ | ||||
| void DopeBinTree<T>::InOrderTraversal2Array(T* array, AlgoVariant variant){ | ||||
|   int index = 0; | ||||
|   DopeBinTreeNode<T>* node = root; | ||||
| 
 | ||||
|   switch(variant){ | ||||
|   case AlgoVariant::Recursive: | ||||
|     RecInOrderTraversal(node, &array[index]); | ||||
|     return; | ||||
|   case AlgoVariant::Iter: | ||||
|     IterInOrderTraversal(node, &array[index]); | ||||
|     return; | ||||
|   default: | ||||
|     return; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  *  \brief PostOrderTraversal2Array | ||||
|  * | ||||
|  *  Binary tree traversal that visits left-subtree, right subtree, and | ||||
|  *  then the root node. | ||||
|  * | ||||
|  *  \param The output array | ||||
|  *  \param The algorithm variant | ||||
|  *  \return return type | ||||
|  */ | ||||
| template <class T> | ||||
| void DopeBinTree<T>::RecPostOrderTraversalArray(T* array){ | ||||
| void DopeBinTree<T>::PostOrderTraversal2Array(T* array, AlgoVariant variant){ | ||||
|   int index = 0; | ||||
|   DopeBinTreeNode<T>* node = root; | ||||
| 
 | ||||
|   switch(variant){ | ||||
|   case AlgoVariant::Recursive: | ||||
|     RecPostOrderTraversal(node, &array[index]); | ||||
|     return; | ||||
|   case AlgoVariant::Iter: | ||||
|     IterPostOrderTraversal(node, &array[index]); | ||||
|     return; | ||||
|   default: | ||||
|     return; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -136,7 +136,7 @@ TEST(ChapterFour, TreeTraversal){ | ||||
| 
 | ||||
|   int array[10] = {}; | ||||
| 
 | ||||
|   btree.RecPreOrderTraversalArray(array); | ||||
|   btree.PreOrderTraversal2Array(array, AlgoVariant::Recursive); | ||||
|   CHECK_EQUAL(1, array[0]); | ||||
|   CHECK_EQUAL(2, array[1]); | ||||
|   CHECK_EQUAL(4, array[2]); | ||||
| @ -147,7 +147,7 @@ TEST(ChapterFour, TreeTraversal){ | ||||
| 
 | ||||
|   std::fill(array, array+10, 0); | ||||
| 
 | ||||
|   btree.RecInOrderTraversalArray(array); | ||||
|   btree.InOrderTraversal2Array(array, AlgoVariant::Recursive); | ||||
|   CHECK_EQUAL(4, array[0]); | ||||
|   CHECK_EQUAL(2, array[1]); | ||||
|   CHECK_EQUAL(5, array[2]); | ||||
| @ -158,7 +158,40 @@ TEST(ChapterFour, TreeTraversal){ | ||||
| 
 | ||||
|   std::fill(array, array+10, 0); | ||||
| 
 | ||||
|   btree.RecPostOrderTraversalArray(array); | ||||
|   btree.PostOrderTraversal2Array(array, AlgoVariant::Recursive); | ||||
|   CHECK_EQUAL(4, array[0]); | ||||
|   CHECK_EQUAL(5, array[1]); | ||||
|   CHECK_EQUAL(2, array[2]); | ||||
|   CHECK_EQUAL(6, array[3]); | ||||
|   CHECK_EQUAL(7, array[4]); | ||||
|   CHECK_EQUAL(3, array[5]); | ||||
|   CHECK_EQUAL(1, array[6]); | ||||
| 
 | ||||
|   std::fill(array, array+10, 0); | ||||
| 
 | ||||
|   btree.PreOrderTraversal2Array(array, AlgoVariant::Iter); | ||||
|   CHECK_EQUAL(1, array[0]); | ||||
|   CHECK_EQUAL(2, array[1]); | ||||
|   CHECK_EQUAL(4, array[2]); | ||||
|   CHECK_EQUAL(5, array[3]); | ||||
|   CHECK_EQUAL(3, array[4]); | ||||
|   CHECK_EQUAL(6, array[5]); | ||||
|   CHECK_EQUAL(7, array[6]); | ||||
| 
 | ||||
|   std::fill(array, array+10, 0); | ||||
| 
 | ||||
|   btree.InOrderTraversal2Array(array, AlgoVariant::Iter); | ||||
|   CHECK_EQUAL(4, array[0]); | ||||
|   CHECK_EQUAL(2, array[1]); | ||||
|   CHECK_EQUAL(5, array[2]); | ||||
|   CHECK_EQUAL(1, array[3]); | ||||
|   CHECK_EQUAL(6, array[4]); | ||||
|   CHECK_EQUAL(3, array[5]); | ||||
|   CHECK_EQUAL(7, array[6]); | ||||
| 
 | ||||
|   std::fill(array, array+10, 0); | ||||
| 
 | ||||
|   btree.PostOrderTraversal2Array(array, AlgoVariant::Iter); | ||||
|   CHECK_EQUAL(4, array[0]); | ||||
|   CHECK_EQUAL(5, array[1]); | ||||
|   CHECK_EQUAL(2, array[2]); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user