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] | ** Stacks and Queues [0/2] | ||||||
| - [ ] Stack Min (CTCI: 3.1) | - [ ] Stack Min (CTCI: 3.1) | ||||||
| - [ ] Sort Stack (CTCI: 3.5) | - [ ] Sort Stack (CTCI: 3.5) | ||||||
| ** Trees and Graphs [4/9] | ** Trees and Graphs [7/9] | ||||||
| - [X] Implement binary tree object | - [X] Implement binary tree object | ||||||
|   - Insert breadth first |   - Insert breadth first | ||||||
| - [X] Recursive Pre-order traversal | - [X] Recursive Pre-order traversal | ||||||
| - [X] Recursive In-order traversal | - [X] Recursive In-order traversal | ||||||
| - [X] Recursive Post-order traversal | - [X] Recursive Post-order traversal | ||||||
| - [ ] Non-Recursive Pre-order traversal | - [X] Non-Recursive Pre-order traversal | ||||||
| - [ ] Non-Recursive In-order traversal | - [X] Non-Recursive In-order traversal | ||||||
| - [ ] Non-Recursive Post-order traversal | - [X] Non-Recursive Post-order traversal | ||||||
| - [ ] Min Heap | - [ ] Min Heap | ||||||
| - [ ] Binary Search | - [ ] Binary Search | ||||||
| ** C/C++ [2/5] | ** C/C++ [2/5] | ||||||
|  | |||||||
| @ -1,6 +1,12 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <queue> | #include <queue> | ||||||
|  | #include <stack> | ||||||
|  | 
 | ||||||
|  | typedef enum AlgoVariant_E{ | ||||||
|  |   Recursive, | ||||||
|  |   Iter, | ||||||
|  | }AlgoVariant; | ||||||
| 
 | 
 | ||||||
| template <class T> | template <class T> | ||||||
| class DopeBinTreeNode{ | class DopeBinTreeNode{ | ||||||
| @ -23,6 +29,9 @@ class DopeBinTree{ | |||||||
|   T* RecPreOrderTraversal(DopeBinTreeNode<T>* node, T* out); |   T* RecPreOrderTraversal(DopeBinTreeNode<T>* node, T* out); | ||||||
|   T* RecInOrderTraversal(DopeBinTreeNode<T>* node, T* out); |   T* RecInOrderTraversal(DopeBinTreeNode<T>* node, T* out); | ||||||
|   T* RecPostOrderTraversal(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: | public: | ||||||
|   DopeBinTree(T data); |   DopeBinTree(T data); | ||||||
|   DopeBinTree(); |   DopeBinTree(); | ||||||
| @ -30,9 +39,9 @@ public: | |||||||
|   void insert(T data); |   void insert(T data); | ||||||
|   bool isEmpty(); |   bool isEmpty(); | ||||||
|   DopeBinTreeNode<T>* getRoot(){return root;} |   DopeBinTreeNode<T>* getRoot(){return root;} | ||||||
|   void RecPreOrderTraversalArray(T* array); |   void PreOrderTraversal2Array(T* array, AlgoVariant variant); | ||||||
|   void RecInOrderTraversalArray(T* array); |   void InOrderTraversal2Array(T* array, AlgoVariant variant); | ||||||
|   void RecPostOrderTraversalArray(T* array); |   void PostOrderTraversal2Array(T* array, AlgoVariant variant); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Implementations ___________________________________________________
 | // Implementations ___________________________________________________
 | ||||||
| @ -147,26 +156,145 @@ T* DopeBinTree<T>::RecPostOrderTraversal(DopeBinTreeNode<T>* node, T* out){ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <class T> | template <class T> | ||||||
| void DopeBinTree<T>::RecPreOrderTraversalArray(T* array){ | void DopeBinTree<T>::IterPreOrderTraversal(DopeBinTreeNode<T>* node, T* out){ | ||||||
|   int index = 0; |   std::stack<DopeBinTreeNode<T>*> s = {}; | ||||||
|   DopeBinTreeNode<T>* node = root; |   s.push(node); | ||||||
| 
 | 
 | ||||||
|   RecPreOrderTraversal(node, &array[index]); |   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> | template <class T> | ||||||
| void DopeBinTree<T>::RecInOrderTraversalArray(T* array){ | void DopeBinTree<T>::IterPostOrderTraversal(DopeBinTreeNode<T>* node, T* out){ | ||||||
|   int index = 0; |   std::stack<DopeBinTreeNode<T>*> s_tmp = {}; | ||||||
|   DopeBinTreeNode<T>* node = root; |   std::stack<DopeBinTreeNode<T>*> s_fin = {}; | ||||||
| 
 | 
 | ||||||
|   RecInOrderTraversal(node, &array[index]); |   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> | template <class T> | ||||||
| void DopeBinTree<T>::RecPostOrderTraversalArray(T* array){ | 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>::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>::PostOrderTraversal2Array(T* array, AlgoVariant variant){ | ||||||
|   int index = 0; |   int index = 0; | ||||||
|   DopeBinTreeNode<T>* node = root; |   DopeBinTreeNode<T>* node = root; | ||||||
| 
 | 
 | ||||||
|   RecPostOrderTraversal(node, &array[index]); |   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] = {}; |   int array[10] = {}; | ||||||
| 
 | 
 | ||||||
|   btree.RecPreOrderTraversalArray(array); |   btree.PreOrderTraversal2Array(array, AlgoVariant::Recursive); | ||||||
|   CHECK_EQUAL(1, array[0]); |   CHECK_EQUAL(1, array[0]); | ||||||
|   CHECK_EQUAL(2, array[1]); |   CHECK_EQUAL(2, array[1]); | ||||||
|   CHECK_EQUAL(4, array[2]); |   CHECK_EQUAL(4, array[2]); | ||||||
| @ -147,7 +147,7 @@ TEST(ChapterFour, TreeTraversal){ | |||||||
| 
 | 
 | ||||||
|   std::fill(array, array+10, 0); |   std::fill(array, array+10, 0); | ||||||
| 
 | 
 | ||||||
|   btree.RecInOrderTraversalArray(array); |   btree.InOrderTraversal2Array(array, AlgoVariant::Recursive); | ||||||
|   CHECK_EQUAL(4, array[0]); |   CHECK_EQUAL(4, array[0]); | ||||||
|   CHECK_EQUAL(2, array[1]); |   CHECK_EQUAL(2, array[1]); | ||||||
|   CHECK_EQUAL(5, array[2]); |   CHECK_EQUAL(5, array[2]); | ||||||
| @ -158,7 +158,40 @@ TEST(ChapterFour, TreeTraversal){ | |||||||
| 
 | 
 | ||||||
|   std::fill(array, array+10, 0); |   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(4, array[0]); | ||||||
|   CHECK_EQUAL(5, array[1]); |   CHECK_EQUAL(5, array[1]); | ||||||
|   CHECK_EQUAL(2, array[2]); |   CHECK_EQUAL(2, array[2]); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user