Created
January 19, 2016 02:31
-
-
Save ijklr/946ccd37f7e22374c59a to your computer and use it in GitHub Desktop.
Depth First Search in C++. To compile: g++ -std=c++11 dfs.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Title: Depth first search in C++ | |
//Author: Shaun Cheng | |
//Date: 1/18/2016 | |
#include <iostream> | |
#include <array> | |
#include <vector> | |
#include <string> | |
#include <stack> | |
using namespace std; | |
////////////////////////////////////////////////////////// | |
//This is an iterative DFS implementation using stack on heap memory. | |
//The children of each node is an iterable container, else it won't compile. | |
//Parameters: | |
//1)pass node, the root of the tree | |
//2)pass a predicate that has a function: bool operator(). | |
//Returns: | |
//the node which passes the predicate, or, nullptr if such node cannot be found. | |
//Time Complexity: | |
//O(N) where N is num of nodes. | |
//Space Complexity: | |
//O(N) where N is num of nodes. | |
//Note: a recursive implementation could run faster and use less memory. | |
//However, since we are not given a balanced tree, a recursive solution | |
//runs the risk of stack overflow for high trees. | |
//Hence an iterative implementation is chosen here. | |
////////////////////////////////////////////////////////// | |
template <class T, class UnaryPredicate> | |
T* dfs(T *node, UnaryPredicate pred) | |
{ | |
stack<T*> dfs_stack; | |
if(node) dfs_stack.push(node); | |
while(!dfs_stack.empty()) { | |
T *top = dfs_stack.top(); | |
dfs_stack.pop(); | |
if(pred(*top)) return top; | |
for(auto n:top->children) | |
if(n) dfs_stack.push(n); | |
} | |
return nullptr; | |
} | |
////////////////////////////////////////////////////////// | |
//NOTE: The following code is to test the above function works. | |
//For the code to compile, a node much have public members: | |
//name: a string denoteing name of the node | |
//children: a container(w/ iterator interface) for its child nodes; | |
////////////////////////////////////////////////////////// | |
//prints tree in human readable format | |
template <class T> | |
void print_tree(T *node, int offset=0) | |
{ | |
if(node == nullptr) return; | |
for(int i=0; i<offset; ++i) cout <<"|_"; | |
cout <<node->name<<endl; | |
++offset; | |
for(auto n:node->children) print_tree(n, offset); | |
} | |
//test dfs with general K-ary tree | |
//name is string | |
//children container is vector | |
void test_K_ary_tree(const string &search_key) | |
{ | |
struct TreeNode { | |
TreeNode(){} | |
TreeNode(const string &s):name(s){} | |
string name; | |
vector<TreeNode*> children; | |
}; | |
TreeNode a("a"); | |
TreeNode b("b"); | |
TreeNode c("c"); | |
TreeNode d("d"); | |
TreeNode e("e"); | |
TreeNode f("f"); | |
TreeNode g("g"); | |
TreeNode h("h"); | |
a.children.push_back(&b); | |
a.children.push_back(&c); | |
b.children.push_back(&d); | |
b.children.push_back(&e); | |
b.children.push_back(&f); | |
c.children.push_back(&g); | |
g.children.push_back(&h); | |
cout <<"Printing the K-ary tree:"<<endl; | |
print_tree(&a); | |
auto pred = [&search_key](const TreeNode &node) { | |
return 0 == node.name.compare(search_key); | |
}; | |
cout <<"\nThe search result using dfs for name '"<<search_key<<"' is:\n"; | |
print_tree(dfs(&a, pred)); | |
} | |
//test dfs with a binary tree | |
//name is integer | |
//children container is c++11 array | |
void test_binary_tree(int search_key) | |
{ | |
struct Node{ | |
Node(){} | |
Node(int i):name(i){} | |
int name; | |
array<Node*, 2> children = {{nullptr, nullptr}}; | |
}; | |
Node a(1); | |
Node b(2); | |
Node c(3); | |
Node d(4); | |
Node e(5); | |
Node f(6); | |
Node g(7); | |
Node h(8); | |
a.children[0] = &b; | |
a.children[1] = &c; | |
b.children[0] = &d; | |
b.children[1] = &e; | |
c.children[0] = &g; | |
c.children[1] = &h; | |
cout <<"Printing the binary tree:"<<endl; | |
print_tree(&a); | |
auto pred = [search_key](const Node &node) { | |
return node.name == search_key; | |
}; | |
cout <<"\nThe search result using dfs for name '"<<search_key<<"' is:\n"; | |
print_tree(dfs(&a, pred)); | |
} | |
//main function to test *-first search | |
int main() | |
{ | |
cout <<">>>>>>>>>>>>>>>>>>>TESTING K-ARY TREE<<<<<<<<<<<<<<<<<<<<<<<<<<" << endl; | |
test_K_ary_tree("g"); | |
cout <<">>>>>>>>>>>>>>>>>>>TESTING BINARY TREE<<<<<<<<<<<<<<<<<<<<<<<<<<" << endl; | |
test_binary_tree(2); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment