二叉树的遍历
说一下四个非递归遍历的思路。
先序的非递归遍历最好理解,先将根节点节点入栈,进入循环,将栈顶元素出栈,输出节点数据,然后将出栈节点右孩子入栈,再压入左孩子,这样的顺序入站之后栈顶节点就是上一个节点的左孩子。重复这个过程直到栈空遍历完成。
中序的非递归遍利用一个栈保存上一个节点,首先左子树一路走到底,遇到叶子节点之后栈顶元素弹出,然后将将弹出的节点的右子树入栈。
后序遍历用了两个栈,我们先看一下图中的二叉树
图:
该二叉树的先序遍历为:1 2 3 4 5 6 7 8 9
后序遍历为:4 3 6 5 2 8 9 7 1
后序遍历的倒置序列是:1 7 9 8 2 5 6 3 4,仔细观察该序列就会发现它是上图中的二叉树交换左右子树之后的先序遍历。所以我们只需要将该序列倒置就能够得到后序遍历的序列里。所以后序遍历这里使用了两个栈,因为是交换左右子树所以使用反过来的先序遍历,但是不需要输出,只需要将栈一弹出的数据压入栈二。等遍历结束之后输出栈二内的数据。
层次遍历的非递归使用队列来实现代码和先序遍历差不多,先将根节点入队,取队头结点输出节点数据,将对头结点出队,然后将出队的节点的左孩子入队,在将其右孩子入队,如果画出队列中的数据情况会发现,每一层节点有从左之后在队列里,只需要一个个出队输出就可以了。
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
//节点类型
struct Node
{
int data;
Node *lchild,*rchild;
};
//建树
void CreateTree(Node* &root)
{
int data;
cin>>data;
if(data==-1)
{
root=nullptr;
}
else
{
root=new Node();
root->data=data;
CreateTree(root->lchild);
CreateTree(root->rchild);
}
}
//前序递归
void PreOrderWithRecursive(Node *root)
{
if(root==nullptr)
return;
else
{
cout<<root->data<<" ";
PreOrderWithRecursive(root->lchild);
PreOrderWithRecursive(root->rchild);
}
}
//中续递归
void MidOrderWithRecursive(Node *root)
{
if(root==nullptr)
return;
else
{
MidOrderWithRecursive(root->lchild);
cout<<root->data<<" ";
MidOrderWithRecursive(root->rchild);
}
}
//后续递归
void PostOrderWithRecursive(Node *root)
{
if(root==nullptr)
return;
else
{
PostOrderWithRecursive(root->lchild);
PostOrderWithRecursive(root->rchild);
cout<<root->data<<" ";
}
}
//前序非递归
void PreOrderWithOutRecursive(Node *root)
{
stack<Node*> s;
Node *r=root;
while(r!=nullptr||!s.empty())
{
if(r)
{
cout<<r->data<<" ";
s.push(r);
r=r->lchild;
}
else
{
r=s.top();
s.pop();
r=r->rchild;
}
}
}
//中序非递归
void MidOrderWithOutRecursive(Node *root)
{
stack<Node*> s;
Node *p=root;
while(p!=nullptr||!s.empty())
{
if(p)
{
s.push(p);
p=p->lchild;
}
else
{
p=s.top();
cout<<p->data<<" ";
p=p->rchild;
s.pop();
}
}
}
//后续非递归
void PostOrderWithOutRecursive(Node *root)
{
stack<Node*> s1;
stack<int> s2;
Node *p=root;
s1.push(p);
while(!s1.empty())
{
p=s1.top();
s2.push(p->data);
s1.pop();
if(p->lchild)
s1.push(p->lchild);
if(p->rchild)
s1.push(p->rchild);
}
while(!s2.empty())
{
cout<<s2.top()<<" ";
s2.pop();
}
}
//层序
void LevelOrder(Node *root)
{
queue<Node*> q;
Node *p=root;
q.push(p);
while(!q.empty())
{
p=q.front();
cout<<p->data<<" ";
q.pop();
if(p->lchild)
q.push(p->lchild);
if(p->rchild)
q.push(p->rchild);
}
}
int main()
{
//1 2 3 4 -1 -1 -1 5 6 -1 -1 -1 7 8 -1 -1 9 -1 -1
Node *root;
cout<<"建树:";
CreateTree(root);
cout<<"递归前序遍历:";
PreOrderWithRecursive(root);
cout<<endl<<"非递归前序遍历:";
PreOrderWithOutRecursive(root);
cout<<endl<<"递归中序遍历:";
MidOrderWithRecursive(root);
cout<<endl<<"非递归中序遍历:";
MidOrderWithOutRecursive(root);
cout<<endl<<"递归后序遍历:";
PostOrderWithRecursive(root);
cout<<endl<<"非递归后序遍历:";
PostOrderWithOutRecursive(root);
cout<<endl<<"层序遍历:";
LevelOrder(root);
return 0;
}