1. 數據結構及遍歷方法定義
/*
* binarytree.h
*/
#ifndef BINARYTREE_H_
#define BINARYTREE_H_
// 二叉樹幾點包含的實體數據類型
typedef char elementType;
// 定義而二叉樹節點數據結構
struct BinaryTreeNode {
elementType data;
BinaryTreeNode* left; // left child
BinaryTreeNode* right; // right child
};
// 二叉樹及節點
typedef BinaryTreeNode btNode;
// 二叉樹(root節點)
typedef BinaryTreeNode btree;
// 遞歸先序遍歷
void rpre_order(btree*);
// 遞歸後續遍歷
void rpost_order(btree*);
// 遞歸中序遍歷
void rin_order(btree*);
// 非遞歸前序遍歷
void pre_order(btree*);
// 非遞歸後續遍歷
void post_order(btree*);
// 非遞歸中序遍歷
void in_order(btree*);
// 廣度優先遍歷
void bfs_order(btree*);
// 銷燬樹
void destory_btree(btree*);
#endif /* BINARYTREE_H_ */
2. 遍歷方法實現
2.1 遞歸遍歷
/*
* BinaryTree.cpp
*/
#include "binarytree.h"
#include <iostream>
#include <malloc.h>
#include <stack>
#include <queue>
using namespace std;
//--------------------------------------------------
// 遞歸先序遍歷
void rpre_order(btree* tree) {
btNode * p = tree;
if (NULL == p) {
return;
}
cout << p->data << " ";
rpre_order(p->left);
rpre_order(p->right);
}
// 遞歸後續遍歷
void rpost_order(btree* tree) {
btNode* p = tree;
if (NULL == p)
return;
rpost_order(p->left);
rpost_order(p->right);
cout << p->data << " ";
}
// 遞歸中序遍歷
void rin_order(btree* tree) {
btNode* p = tree;
if (NULL == p)
return;
rin_order(p->left);
cout << p->data << " ";
rin_order(p->right);
}
2.2 消除遞歸
//--------------------------------------------------
// 非遞歸前序遍歷
void pre_order(btree* tree) {
btNode * p = tree;
if (NULL == p)
return;
stack<btNode*>* st = new stack<btNode*>();
st->push(p);
while (!st->empty()) {
p = st->top();
st->pop();
cout << p->data << " ";
if (NULL != p->right) {
st->push(p->right);
}
if (NULL != p->left) {
st->push(p->left);
}
}
delete st;
}
// 非遞歸後續遍歷
//須要注意的是 : 非遞歸後序遍歷方法相對實現比較困難,主要緣由就在於父子節點訪問缺少連續
// 解決思路是將前一個訪問節點記憶下來,並判斷和當前節點之間的關係再作處理
void post_order(btree* tree) {
btNode* curr = tree; // 記錄當前執行的節點
btNode* prev = NULL; // 記錄前一個訪問的節點
if (NULL == curr) {
return;
}
stack<btNode*>* st = new stack<btNode*>();
st->push(curr);
while (!st->empty()) {
curr = st->top();
// 若是該節點沒有孩子節點則能夠直接訪問
if (NULL == curr->left && NULL == curr->right) {
cout << curr->data << " ";
st->pop();
prev = curr;
continue;
}
// 若是該節點的孩子節點已經被訪問過了,也可直接訪問
if (NULL != prev && (prev == curr->right || prev == curr->left)) {
cout << curr->data << " ";
st->pop();
prev = curr;
continue;
}
// 除了上述狀況則須要將孩子節點入棧
if (NULL != curr->right) {
st->push(curr->right);
}
if (NULL != curr->left) {
st->push(curr->left);
}
}
delete st;
}
// 非遞歸中序遍歷
void in_order(btree* tree) {
btNode* p = tree;
if (NULL == p)
return;
stack<btNode*>* st = new stack<btNode*>();
while (NULL != p || !st->empty()) {
while (NULL != p) {
st->push(p);
p = p->left;
}
if (!st->empty()) {
p = st->top();
st->pop();
cout << p->data << " ";
p = p->right;
}
}
delete st;
}
2.3 逐層遍歷
//--------------------------------------------------
// 廣度優先
void bfs_order(btree* tree) {
btNode* p = tree;
if (NULL == p) {
return;
}
queue<btNode*> * qu = new queue<btNode*>();
qu->push(p);
while (!qu->empty()) {
p = qu->front();
qu->pop();
cout << p->data << " ";
if (NULL != p->left) {
qu->push(p->left);
}
if (NULL != p->right) {
qu->push(p->right);
}
}
delete qu;
}
//--------------------------------------------------
// 銷燬二叉樹
void destory_btree(btree* tree) {
btNode* p = tree;
if (NULL == p) {
return;
}
queue<btNode*> * qu = new queue<btNode*>();
qu->push(p);
while (!qu->empty()) {
p = qu->front();
qu->pop();
if (NULL != p->left) {
qu->push(p->left);
}
if (NULL != p->right) {
qu->push(p->right);
}
free(p);
}
delete qu;
}
3. 測試
//============================================================================
// Name : main.cpp
//============================================================================
#include <iostream>
#include "binarytree.h"
#include <malloc.h>
using namespace std;
btNode* init_tree() {
btNode* a = (btNode *) malloc(sizeof(btNode));
a->data = 'A';
a->left = a->right = NULL;
btNode* b = (btNode *) malloc(sizeof(btNode));
b->data = 'B';
b->left = b->right = NULL;
btNode* c = (btNode *) malloc(sizeof(btNode));
c->data = 'C';
c->left = c->right = NULL;
btNode* d = (btNode *) malloc(sizeof(btNode));
d->data = 'D';
d->left = d->right = NULL;
btNode* e = (btNode *) malloc(sizeof(btNode));
e->data = 'E';
e->left = e->right = NULL;
btNode* f = (btNode *) malloc(sizeof(btNode));
f->data = 'F';
f->left = f->right = NULL;
btNode* g = (btNode *) malloc(sizeof(btNode));
g->data = 'G';
g->left = g->right = NULL;
btNode* h = (btNode *) malloc(sizeof(btNode));
h->data = 'H';
h->left = h->right = NULL;
btNode* i = (btNode *) malloc(sizeof(btNode));
i->data = 'I';
i->left = i->right = NULL;
a->left = b;
a->right = c;
b->right = d;
c->left = e;
d->left = f;
d->right = g;
e->left = h;
e->right = i;
return a;
}
int main() {
cout << "Binary Tree Test" << endl; // prints Binary Tree Test
// init tree
btree * tree = init_tree();
cout << "Pre order" << endl;
rpre_order(tree);
cout << endl;
pre_order(tree);
cout << endl;
cout << "Post order" << endl;
rpost_order(tree);
cout << endl;
post_order(tree);
cout << endl;
cout << "In order" << endl;
rin_order(tree);
cout << endl;
in_order(tree);
cout << endl;
cout << "BFS order" << endl;
bfs_order(tree);
cout << endl;
//
destory_btree(tree);
return 0;
}
測試結果以下:
Binary Tree Test
Pre order
A B D F G C E H I
A B D F G C E H I
Post order
F G D B H I E C A
F G D B H I E C A
In order
B F D G A H E I C
B F D G A H E I C
BFS order
A B C D E F G H I