目录
一、二叉树的遍历算法概述
二叉树的常见的遍历算法有:先序遍历、中序遍历、后序遍历以及层序遍历,其中先序、中序、后序遍历的递归算法实现相对简单,但非递归算法的执行效率更高,并且非递归算法需要借助栈来实现。另外,二叉树的层序算法的实现需要借助队列实现。以下给出的是二叉树的链式存储结构:
typedef struct BiTNode {
elemtype data;
struct BiTNode* lchild;
struct BiTNode* rchild;
}BiTNode, * BiTree;
二、二叉树的前序遍历
1.前序遍历递归实现
void PreOrder(BiTree T) {
if (T) {
visit(T);//访问结点
PreOrder(T->lchild);//递归遍历左孩子
PreOrder(T->rchild);//递归遍历右孩子
}
}
2.前序遍历非递归实现
void PreOrder(BiTree T) {
BiTNode* p = T;
stack<BiTNode*> s;//创建一个栈存储当前结点的父结点
while (p || !s.empty()) {
if (p) {
visit(p);
s.push(p);
p = p->lchild;
}
else {
p = s.top();
s.pop();
p = p->rchild;
}
}
}
三、二叉树的中序遍历
1.中序遍历递归实现
void InOrder(BiTree T) {
if (T) {
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}
2.中序遍历非递归实现
void InOrder(BiTree T) {
BiTNode* p = T;
stack<BiTNode*> s;
while (p || !s.empty()) {
if (p) {
s.push(p);
p = p->lchild;
}
else {
p = s.top();
s.pop();
visit(p);
p = p->rchild;
}
}
}
四、二叉树的后序遍历
1.后序遍历递归实现
void PostOrder(BiTree T) {
if (T) {
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
2.后序遍历非递归实现
相对于前序和中序遍历的非递归算法,后序遍历的非递归算法有所不同。当用栈来存储结点时,必须分清返回根结点时,是从左子树返回,还是从右子树返回。所以,使用赋值指针r,其指向最近访问过的结点。
void PostOrder(BiTree T) {
BiTNode* p = T, * r = NULL;//r用于标记为已经访问过的结点
stack<BiTNode*> s;
while (p || !s.empty()) {
if (p) {
s.push(p);
p = p->lchild;
}
else {
p = s.top();
if (p->rchild && p->rchild != r) {
p = p->rchild;
s.push(p);
p = p->lchild;
}
else {
s.pop();
visit(p);
r = p;
p = NULL;
}
}
}
}
五、二叉树的层序遍历
void LevelOrder(BiTree T) {
BiTNode* p = T;
queue<BiTNode*> q;
if (p) q.push(p);
while (!q.empty()) {
p = q.front();
visit(p);
q.pop();//将队首的元素弹出
if (p->lchild) q.push(p->lchild);
if (p->rchild) q.push(p->rchild);
}
}