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