先定义结点的结构如下:
//二叉树结点
typedef struct BiTNode{
//数据
char data;
//左右孩子指针
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTreePtr;
后序遍历最难,先搞后序遍历。
递归:
//后序遍历
void PostOrder(BiTreePtr T)
{
if(nullptr != T)
{
//访问左子结点
PostOrder(T->lchild);
//访问右子结点
PostOrder(T->rchild);
//访问根节点
Visit(T);
}
}
迭代:
后序遍历要求在遍历完左右子树后,再访问根。需要判断根结点的左右子树是否均遍历过。因为相对于左右子结点来说,根结点总是被访问。所以我们只需要额外再增加一个指针,指向刚刚访问过的结点即可。只要刚刚访问过的结点是当前结点的右结点,或者当前结点的右结点为空,那么就访问当前结点。否则,去访问当前结点的右子结点。
void PostOrder_iteration(BiTreePtr T) // 后序遍历的非递归
{
std::stack<BiTreePtr> S;
BiTreePtr curr = T ; // 指向当前要检查的节点
BiTreePtr previsited = nullptr; // 指向前一个被访问的节点
while(nullptr != curr || !S.empty()) // 栈空时结束
{
while(nullptr != curr) // 一直向左走直到为空
{
S.push(curr);
curr = curr->lchild;
}
curr = S.top();
// 当前节点的右孩子如果为空或者已经被访问,则访问当前节点
if(nullptr == curr->rchild || curr->rchild == previsited)
{
cout<<curr->data<<" ";
previsited = curr;
S.pop();
curr = nullptr;
}
else
curr = curr->rchild; // 否则访问右孩子
}
}
中序遍历
递归:
//中序遍历
void InOrder(BiTreePtr T){
if(nullptr != T !){
//访问左子结点
InOrder(T->lchild);
//访问根节点
Visit(T);
//访问右子结点
InOrder(T->rchild);
}
}
迭代:
void InOrder_iteration(BiTreePtr T) // 中序遍历的非递归
{
if(nullptr == T)
return ;
BiTreePtr curr = T; // 指向当前要检查的节点
std::stack<BiTreePtr> s;
while(nullptr != curr || !s.empty())
{
while(nullptr != curr)
{
s.push(curr);
curr = curr->lchild;
}
curr = s.top();
s.pop();
cout<<curr->data<<" ";
curr = curr->rchild;
}
}
前序遍历
递归:
//前序遍历
void PreOrder(BiTNodePtr T)
{
if(nullptr == T)
return ;
printf("%c ", T->data); //输出数据
PreOrder(T->lchild); //递归调用,前序遍历左子树
PreOrder(T->rchild); //递归调用,前序遍历右子树
}
迭代:
void PreOrder_iteration(BiTreePtr T) //先序遍历的非递归
{
if(nullptr != T)
return ;
std::stack<BiTreePtr> s;
s.push(T);
while(!s.empty())
{
BiTree temp = s.top();
std::cout<<temp->data<<" ";
s.pop();
if(temp->rchild)
s.push(temp->rchild);
if(temp->lchild)
s.push(temp->lchild);
}
}
方法二,还是迭代:
void PreOrder_iteration(BiTreePtr T) //先序遍历的非递归
{
if(nullptr != T)
return;
std::stack<BiTreePtr> s;
BiTreePtr curr = T;
while(nullptr != curr || !s.empty())
{
while(nullptr != curr)
{
std::cout<<curr->data<<" ";
s.push(curr);
curr = curr->lchild;
}
curr = s.top();
s.pop();
curr = curr->rchild;
}
}
最后,还有二叉树的层次遍历。对于层次遍历,类似于图的广度优先DFS。这就该用队列来实现了。
这篇博文写的太长了,新开一篇来写层次遍历及相关变形吧。
http://blog.csdn.net/friendbkf/article/details/50316209