二叉树遍历:递归+非递归+逐层遍历

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