There are basically two ways of traversing a binary tree
1. Depth First Traversals
2. Breadth First Traversal
Depth First Traversal
A binary tree can be traversed in three ways using the depth first approach namely
1. Inorder Traversal
template <typename T> void BTTraveller<T>::inOrder(BSTNode<T> *node, std::deque<T> &out) { if(node) { inOrder(node->left, out); out.push_back(node->key); inOrder(node->right, out); } }
2. Preorder Traversal
template <typename T> void BTTraveller<T>::preOrder(BSTNode<T> *node, std::deque<T> &out) { if(node) { out.push_back(node->key); preOrder(node->left, out); preOrder(node->right, out); } }
3. Postorder Traversal
template <typename T> void BTTraveller<T>::postOrder(BSTNode<T> *node, std::deque<T> &out) { if(node) { postOrder(node->left, out); postOrder(node->right, out); out.push_back(node->key); } }
Breadth First Traversal
There is only one kind of Breadth first traversal viz.
Level Order traversal
. This traversal does not move along the branches of the tree but makes use of a FIFO queue. In the sample code, I have used std::deque as the helper queue for achieving the same.template <typename T> void BTTraveller<T>::levelOrder(BST<T> *bstree, std::deque<T> &out) { std::deque<BSTNode<T>*> hQ; hQ.push_back(bstree->m_root); levelOrder(hQ, out); } template <typename T> void BTTraveller<T>::levelOrder(std::deque<BSTNode<T>*> &hQ, std::deque<T> &out) { while(hQ.empty() == false) { BSTNode<T> *current = hQ.front(); if(current != NULL) { hQ.pop_front(); out.push_back(current->key); addChildren(current, hQ); } } }
The
BTTraveller
class takes care of returning Binary Tree node elements in the order you are traversing the tree.1 #ifndef _BTTraveller_H_ 2 #define _BTTraveller_H_ 3 #include "BSTNode.h" 4 #include <deque> 5 6 //File: BTTraveller.h 7 namespace algorithms 8 { 9 template <typename T> 10 class BTTraveller 11 { 12 public: 13 static void inOrder(BST<T> *bstree, std::deque<T> &elems); 14 static void preOrder(BST<T> *bstree, std::deque<T> &elems); 15 static void postOrder(BST<T> *bstree, std::deque<T> &elems); 16 static void levelOrder(BST<T> *bstree, std::deque<T> &elems); 17 18 private: 19 static void inOrder(BSTNode<T> *node, std::deque<T> &elems); 20 static void preOrder(BSTNode<T> *node, std::deque<T> &elems); 21 static void postOrder(BSTNode<T> *node, std::deque<T> &elems); 22 static void levelOrder(std::deque<BSTNode<T>*> &helperQ, std::deque<T> &elems); 23 static void addChildren(BSTNode<T> *node, std::deque<BSTNode<T>*> &helperQ); 24 25 BTTraveller(); 26 BTTraveller(const BTTraveller&); 27 const BTTraveller& operator=(const BTTraveller&); 28 }; 29 }; 30 31 #include "BTTraveller.hpp" 32 #endif //_BTTraveller_H_
1 //File: BTTraveller.hpp 2 namespace algorithms 3 { 4 template <typename T> 5 void BTTraveller<T>::inOrder(BST<T> *bstree, std::deque<T> &out) 6 { 7 inOrder(bstree->m_root, out); 8 } 9 10 template <typename T> 11 void BTTraveller<T>::preOrder(BST<T> *bstree, std::deque<T> &out) 12 { 13 preOrder(bstree->m_root, out); 14 } 15 16 template <typename T> 17 void BTTraveller<T>::postOrder(BST<T> *bstree, std::deque<T> &out) 18 { 19 postOrder(bstree->m_root, out); 20 } 21 22 template <typename T> 23 void BTTraveller<T>::levelOrder(BST<T> *bstree, std::deque<T> &out) 24 { 25 std::deque<BSTNode<T>*> hQ; 26 hQ.push_back(bstree->m_root); 27 levelOrder(hQ, out); 28 } 29 30 template <typename T> 31 void BTTraveller<T>::inOrder(BSTNode<T> *node, std::deque<T> &out) 32 { 33 if(node) 34 { 35 inOrder(node->left, out); 36 out.push_back(node->key); 37 inOrder(node->right, out); 38 } 39 } 40 41 template <typename T> 42 void BTTraveller<T>::preOrder(BSTNode<T> *node, std::deque<T> &out) 43 { 44 if(node) 45 { 46 out.push_back(node->key); 47 preOrder(node->left, out); 48 preOrder(node->right, out); 49 } 50 } 51 52 template <typename T> 53 void BTTraveller<T>::postOrder(BSTNode<T> *node, std::deque<T> &out) 54 { 55 if(node) 56 { 57 postOrder(node->left, out); 58 postOrder(node->right, out); 59 out.push_back(node->key); 60 } 61 } 62 63 template <typename T> 64 void BTTraveller<T>::levelOrder(std::deque<BSTNode<T>*> &hQ, std::deque<T> &out) 65 { 66 while(hQ.empty() == false) 67 { 68 BSTNode<T> *current = hQ.front(); 69 if(current != NULL) 70 { 71 hQ.pop_front(); 72 out.push_back(current->key); 73 addChildren(current, hQ); 74 } 75 } 76 } 77 78 template <typename T> 79 void BTTraveller<T>::addChildren(BSTNode<T> *node, std::deque<BSTNode<T>*> &hQ) 80 { 81 if(node->left != NULL) 82 { 83 hQ.push_back(node->left); 84 } 85 if(node->right != NULL) 86 { 87 hQ.push_back(node->right); 88 } 89 } 90 }
You need to include
BTTraveller
class as a friend
class in both the BSTNode
as well as BST
class declarations. This ensures that the BTTraveller class has access to private data members of these two classesThe BSTNode class
1 #ifndef _BSTNode_H_ 2 #define _BSTNode_H_ 3 #include <iostream> 4 5 //File: BSTNode.h 6 namespace algorithms 7 { 8 template <typename T> 9 class BST; 10 11 template <typename T> 12 class BTTraveller; 13 14 template <typename T> 15 class BSTNode 16 { 17 public: 18 BSTNode(T key); 19 ~BSTNode(); 20 21 friend class BST<T>; 22 friend class BTTraveller<T>; 23 24 private: 25 BSTNode<T> *left; 26 BSTNode<T> *right; 27 T key; 28 }; 29 }; 30 31 #include "BSTNode.hpp" 32 #endif //_BSTNode_H_
The BST class
1 #ifndef _BinarySearchTree_H_ 2 #define _BinarySearchTree_H_ 3 #include "BSTNode.h" 4 5 //File: BST.h 6 namespace algorithms 7 { 8 template <typename T> 9 class BTTraveller; 10 11 template <typename T> 12 class BST 13 { 14 public: 15 BST(); 16 ~BST(); 17 18 //modifiers 19 void insert(T key); 20 void remove(T key); 21 void clear(); 22 23 //accessors 24 bool find(T key); 25 bool isEmpty() const; 26 27 friend class BTTraveller<T>; 28 29 private: 30 void remove(BSTNode<T> **node); 31 void clear(BSTNode<T> *node); 32 BSTNode<T>** find(BSTNode<T> **node, const T key); 33 BSTNode<T>** getSuccessor(BSTNode<T> **node); 34 BSTNode<T>* getNewNode(T key); 35 36 //instance fields 37 BSTNode<T> *m_root; 38 }; 39 }; 40 41 #include "BST.hpp" 42 #endif //_BinarySearchTree_H_
The
BSTNode.hpp
and BST.hpp
files remains the same as in the postThe Client Program
1 #include "BST.h" 2 #include "BTTraveller.h" 3 #define MAX 20 4 using namespace algorithms; 5 6 //File: Main.cpp 7 8 template <typename T> 9 void DumpDeque(std::deque<T> &q) 10 { 11 std::cout << std::endl; 12 std::deque<T>::const_iterator itr; 13 for(itr = q.cbegin(); itr != q.cend(); ++itr) 14 { 15 std::cout << *itr << " "; 16 } 17 std::cout << std::endl; 18 q.clear(); 19 } 20 21 int main(int argc, char *argv[]) 22 { 23 int nodes[MAX] = { 50, 40, 60, 70, 80, 20, 30, 10, 90, 15, 35, 65, 75, 5, 1, 100, 110, 130, 120, 111 }; 24 BST<int> bstInt; 25 for(int i = 0; i < MAX; ++i) 26 { 27 bstInt.insert(nodes[i]); 28 } 29 30 std::deque<int> elems; 31 BTTraveller<int>::inOrder(&bstInt, elems); 32 DumpDeque(elems); 33 BTTraveller<int>::preOrder(&bstInt, elems); 34 DumpDeque(elems); 35 BTTraveller<int>::postOrder(&bstInt, elems); 36 DumpDeque(elems); 37 BTTraveller<int>::levelOrder(&bstInt, elems); 38 DumpDeque(elems); 39 40 return 0; 41 }
Output
$ ./BinarySearchTree.exe 1 5 10 15 20 30 35 40 50 60 65 70 75 80 90 100 110 111 120 130 50 40 20 10 5 1 15 30 35 60 70 65 80 75 90 100 110 130 120 111 1 5 15 10 35 30 20 40 65 75 111 120 130 110 100 90 80 70 60 50 50 40 60 20 70 10 30 65 80 5 15 35 75 90 1 100 110 130 120 111
Read more ...