简要概述
前序遍历:先输出父节点,再输出左孩子节点,最后输出右孩子节点;
中序遍历:先输出左孩子节点,再输出父节点,最后输出右孩子节点;
后序遍历:先输出左孩子节点,再输出右孩子节点,最后输出父节点;
递归实现
如果对递归的思想还不是很清楚,建议博客入门递归算法入门
#include<iostream>
#include<stack>
using namespace std;
struct BinaryTree {
int data;
BinaryTree *leftchild;
BinaryTree *rightchild;
BinaryTree(int data):data(data), leftchild(NULL), rightchild(NULL){}
};
BinaryTree *BinaryTree;
void InsertNode(BinaryTree *Tree, int data) {
if(data <= Tree->data) {
if(Tree->leftchild != NULL) {
Tree->leftchild = new BinaryTree(data);
} else {
InsertNode(Tree->leftchild, data);
}
} else {
if(Tree->rightchild != NULL) {
Tree->rightchild = new BinaryTree(data);
} else {
InsertNode(Tree->rightchild, data);
}
}
}
void PreOrder(BinaryTree *Tree) {
if(Tree != NULL) {
cout<<Tree->data;
PreOrder(Tree->leftchild);
PreOrder(Tree->rightchild);
}
}
void InOrder(BinaryTree *Tree) {
if(Tree != NULL) {
InOrder(Tree->leftchild);
cout<<Tree->data;
InOrder(Tree->rightchild);
}
}
void PostOrder(BinaryTree *Tree) {
if(Tree != NULL) {
PostOrder(Tree->leftchild);
PostOrder(Tree->rightchild);
cout<<Tree->data;
}
}
非递归实现
前序遍历:根节点入栈,在每次循环中,先取出当前栈顶元素并输出,然后压入右孩子节点,再压入左孩子节点,循环至栈空退出;
中序遍历:根节点赋给当前的临时节点,在每次循环中,若当前的临时节点非空,将当前节点压入栈,往左孩子遍历;若当前的临时节点为空,取栈顶元素并输出,将栈顶元素的右孩子节点赋给当前的临时节点,循环至当前节点为空且栈空退出;
后序遍历:反向思考前序遍历,根节点入栈s1,在每次循环中,先取出当前栈s1的栈顶元素,并压入栈s2中,然后将左孩子节点压入栈s1,再将右孩子节点压入栈s1,循环至栈空;最后按序取出栈s2中元素并输出;
//头文件以及使用命名空间,二叉树的数据结构见上,此处省略
void preOrder(BinaryTree *Tree) {
if(Tree == NULL) {
return ;
}
stack<BinaryTree*> s;
s.push(Tree);
while(!s.empty()) {
BinaryTree *temp = s.top();
s.pop();
cout<<temp->data;
if(temp->rightchild != NULL) {
s.push(s->rightchild);
}
if(temp->leftchild != NULL) {
s.push(s->leftchild);
}
}
}
void inOrder(BinaryTree *Tree) {
stack<BinaryTree*> s;
BinaryTree *temp = Tree;
while(temp != NULL || !s.empty()) {
if(temp != NULL) { //当前节点非空,压入栈,继续往左遍历
s.push(temp);
temp = temp->leftchild;
} else { //当前节点为空,取栈顶元素并输出,将栈顶元素的右孩子节点赋给当前节点
BinaryTree *node = s.top();
s.pop();
cout<<node->data;
temp = node->rightchild;
}
}
}
void postOrder(BinaryTree *Tree) {
stack<BinaryTree*> s1, s2;
s1.push(Tree);
while(!s1.empty()) {
BinaryTree *temp = s1.top();
s1.pop();
s2.push(temp);
if(temp.leftchild != NULL) {
s1.push(temp.leftchild);
}
if(temp.rightchild != NULL) {
s1.push(temp.rightchild);
}
}
while(!s2.empty()) {
cout<<s2.top();
s2.pop();
}
}
深度优先搜索(DFS)
即先序遍历,从根节点开始,先沿着左子树一直遍历,直到叶子节点为止;接着回溯到上一个节点,进行右子树节点的遍历,当所有节点遍历完成之后退出;
广度优先搜索(BFS)
即层次遍历,从根节点开始,对每一层子节点遍历完之后,再开始下一层节点的遍历,当所有节点遍历完成之后推出;
//深度优先遍历
void depthFirstSearch(BinaryTree *Tree) {
stack<BinaryTree*> s;
s.push(Tree);
while(!s.empty()) {
BinaryTree *temp = s.top()
s.pop()
cout<<temp->data;
if(s.rightchild != NULL) {
s.push(s.rightchild);
}
if(s.leftchild != NULL) {
s.puhs(s.leftchild);
}
}
}
//广度优先遍历
void breadthFirstSearch(BinaryTree *Tree) {
queue<BinaryTree*> q;
q.push(Tree);
while(!q.empty()) {
BinaryTree *temp = q.front();
q.pop();
cout<<temp->data;
if(temp.leftchild != NULL) {
q.push(temp->leftchild);
}
if(temp.rightchild != NULL) {
q.push(temp->rightchild);
}
}
}