前言
记录下二叉树的实现以及前序、中序、后序遍历的过程。
二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的。对于二叉树,有深度遍历和广度遍历,深度遍历有前序、中序以及后序三种遍历方法,至于广度遍历,本篇blog暂且按下不表。
因为树的定义本身就是递归定义,因此采用递归的方法去实现树的深度遍历中的三种遍历不仅容易理解而且代码很简洁。而对于广度遍历来说,需要其他数据结构的支撑,比如堆。所以,对于一段代码来说,可读性有时候要比代码本身的效率要重要的多。
3种主要的遍历思想为:
前序遍历:根结点 —> 左子树 —> 右子树
中序遍历:左子树—> 根结点 —> 右子树
后序遍历:左子树 —> 右子树 —> 根结点
下面的示范代码为,输入一个前缀表达式,以此构建二叉树,并依照三种遍历方法分别输出前缀、中缀、后缀表达式。
代码
先上树结点的TreeNode.h文件
#ifndef _TREE_NODE_H
#define _TREE_NODE_H
template<typename T>
class TreeNode{
private:
T data;
TreeNode *lN;
TreeNode *rN;
public:
TreeNode(){
lN = NULL;
rN = NULL;
}
T getData(){
return data;
}
void setData(T a){
this->data = a;
}
TreeNode* getLeft(){
return this->lN;
}
void modLeft(TreeNode* p){
lN = p;
return;
}
TreeNode* getRight(){
return this->rN;
}
void modRight(TreeNode* p){
rN = p;
return;
}
bool isLeaf(){
if ((lN == NULL) && (rN == NULL)) return true;
else return false;
}
void setLeaf(){
this->lN = NULL;
this->rN = NULL;
}
};
#endif
接下来是main.cpp文件。它可以被打包成二叉树类,但我懒得弄了,索性直接写在main里。
#pragma warning(disable:4996)
#include <iostream>
#include <string>
#include "TreeNode.h"
using namespace std;
char nextToken(char infix[]){
static int pos = 0;
while (infix[pos] != '\0' && infix[pos] == ' ') pos++;
return infix[pos++];
}
void preOrder(TreeNode<char>* bt){
if (bt == NULL) return;
cout << bt->getData();
preOrder(bt->getLeft());
preOrder(bt->getRight());
}
void postOrder(TreeNode<char>* bt){
if (bt == NULL) return;
else{
postOrder(bt->getLeft());
postOrder(bt->getRight());
cout << bt->getData();
}
}
void inOrder(TreeNode<char>* bt){
if (bt == NULL) return;
else{
if (!bt->isLeaf())cout << "(";
inOrder(bt->getLeft());
cout << bt->getData();
inOrder(bt->getRight());
if (!bt->isLeaf())cout << ")";
}
}
TreeNode<char>* build(TreeNode<char>* root, char input[]){
char x = nextToken(input);
if (root == NULL){
root = new TreeNode<char>();
}
if (x >= '0'&& x <= '9'){
root->setData(x);
root->setLeaf();
return root;
}
if (x == '+' || x == '-' || x == '*' || x == '/'){
root->setData(x);
root->modLeft(build(root->getLeft(), input));
root->modRight(build(root->getRight(), input));
return root;
}
}
int main(){
string str;
cin >> str;
char buf[100];
int length = str.copy(buf, 100);
buf[length] = '\0';
TreeNode<char> *p = NULL;
p = build(p,buf);
cout << "Prefix" << endl;
preOrder(p);
cout << endl;
cout << "Infix:" << endl;
inOrder(p);
cout << endl;
cout << "Postfix" << endl;
postOrder(p);
}