前言
記錄下二叉樹的實現以及前序、中序、後序遍歷的過程。
二叉樹是一種非常重要的數據結構,很多其它數據結構都是基於二叉樹的基礎演變而來的。對於二叉樹,有深度遍歷和廣度遍歷,深度遍歷有前序、中序以及後序三種遍歷方法,至於廣度遍歷,本篇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);
}