C++详解⼆叉树的三种遍历⽅式
上⼀篇⽂章,讲了⼆叉树的创建——
接下来讲解⼆叉树的三种遍历⽅式:先序(前序)遍历、中序遍历、后序遍历,三种⽅式都是DFS(Depth First Search)深度优先搜索,核⼼思想都是函数的递归(栈),如果你能理解上⾯这篇⽂章中创建⼆叉树的具体过程,那么遍历就轻⽽易举
1.先序遍历
板栗炖鸡
void Former_Order_Traverl(BinTree_Node* p)
{
if(p)
{
cout<<p->data;
Former_Order_Traversal(p->left);
Former_Order_Traversal(p->right);
}
}
下⾯分析具体过程,以上⼀篇⽂章创建的⼆叉树为例,圆圈中的数字为data。从上到下,从左到右给结点编号,遍历顺序为ABDECFG,根-左-右
整个递归过程其实是靠函数栈来实现的,先访问再⼊栈:
1.把根结点指针传进来,判断结点不为空,访问根结点数据,然后将根结点A⼊栈
2.把根结点的left指针(B结点)传进来,判断结点不为空,访问B结点数据,将B结点⼊栈
3.把B结点的left指针(D结点)传进来,判断结点不为空,访问D结点数据,D结点⼊栈
4.把D结点的left指针传进来,指针为空,从栈顶抛出⼀个元素D,处理右⼦树
5.把D的right指针传进来,指针为空,从栈顶抛出⼀个元素B,处理右⼦树
6.把B的right指针(E结点)传进来,判断不为空,访问E结点数据,E结点⼊栈
7.把E结点的left指针传进来,指针为空,从栈顶抛出⼀个元素E,处理右⼦树
8.把E结点的right指针传进来,指针为空,从栈顶抛出⼀个元素A,然后同理
搞清楚函数栈的实现过程后,我们可以利⽤stl中的stack模拟出栈和⼊栈
void Former_Order_Stack(Bintree_Node* p)
{
if(!p)return;//如果是空树,就直接返回
Bintree_Node* temp = p;
做饺子的步骤
stack<Bintree_Node*>s;//创建⼀个数据栈
while(temp !=NULL||!s.empty())//当temp为空指针且栈空时,遍历就结束了
周文王简介
{
while(temp !=NULL)//判断结点是否为空
{
cout << temp->data << endl;//访问数据
电脑怎么连无线网
s.push(temp);//该结点⼊栈
temp = temp->left;//将指针指向左⼦树
}
temp = s.top();//抛出前,获得栈顶元素的引⽤,也就是出栈结点的引⽤家常炖猪肉
s.pop();
temp = temp->right;//将指针指向出栈结点的右⼦树,准备处理
}
}
2.中序遍历
void Middle_Order_Stack(Bintree_Node* p)
{
if(p)
{
Middle_Order_Traversal(p->left);
cout<<p->data;
Middle_Order_Traversal(p->right);
}
}
遍历顺序为DBEAFCG,左-根-右,具体过程如下
1.根结点指针传进来,判断不为空,根结点A⼊栈
2.把根结点的left指针(B结点)传进来,判断不为空,B结点⼊栈
3.把B结点的left指针(D结点)传进来,判断不为空,D结点⼊栈
4.把D结点的left指针传进来,判断为空,抛出栈顶元素D,输出D结点数据
5.把指针指向D结点的right指针,判断为空
知之为知之不知为不知是知也5.把指针指向D结点的right指针,判断为空
6.抛出栈顶元素B,输出B结点数据
7.把指针指向B结点right指针(E结点),判断不为空,E结点⼊栈
8.把指针指向E结点的left指针,判断为空,抛出栈顶E结点,输出结点E数据
9.把指针指向E结点的right指针,判断为空,抛出栈顶A结点,输出A结点数据
…右⼦树同理
弄清楚上述过程后,⽤stack模拟
void Middle_Order_Stack(Bintree_Node* p)
{
if(!p)return;//如果是空树,就直接返回
Bintree_Node* temp = p;
stack<Bintree_Node*>s;
while(temp !=NULL||!s.empty())
{
while(temp !=NULL)
{
s.push(temp);
temp = temp->left;
}
酒枣的功效与作用temp = s.top();夜关门
cout << temp->data << endl;
s.pop();
temp = temp->right;
}
}
3.后序遍历