在考研中考察的几率不大。如果大题考察这个问题难度会很大;小题考察这个问题分值有可能会很高
非递归执行效率高
在这个实现过程中需要使用栈的数据结构点击查看栈相关笔记。
- 构建一个栈 S ,用来接收树的结点。前提是已经层序建好了一棵树
- 每次遍历之前都要从树根开始,用一个新的变量 p 来接收树根的地址(后续会接收其他树结点的地址)。判断p存在或者栈s不为空即可继续。此时栈为空,但是树根存在所以p就存在,所以继续。
- 如果P存在,就将p压入栈s中,然后p指向自己的左孩子。
- 重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P既存在、栈S又不为空,继续。因为P存在,所以将P压入栈S中,然后P指向自己的左孩子
- 重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P既存在、栈S又不为空,继续。因为P存在,所以将P压入栈S中,然后P指向自己的左孩子
重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P不存在,但是栈S不为空,继续。
因为这里p不存在,执行的操作是:栈S执行出栈操作(这里可以加上控制台输出操作),并且将出栈元素赋值给p
- p指向自己的右孩子。
重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P不存在,但是栈S不为空,继续。
因为这里p不存在,执行的操作是:栈S执行出栈操作(这里可以加上控制台输出操作),并且将出栈元素赋值给p
- p指向自己的右孩子。
- 重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P既存在、栈S又不为空,继续。因为P存在,所以将P压入栈S中,然后P指向自己的左孩子
重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P不存在,但是栈S不为空,继续。
因为这里p不存在,执行的操作是:栈S执行出栈操作(这里可以加上控制台输出操作),并且将出栈元素赋值给p
- p指向自己的右孩子。
重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,P不存在,但是栈S不为空,继续。
因为这里p不存在,执行的操作是:栈S执行出栈操作(这里可以加上控制台输出操作),并且将出栈元素赋值给p
- p指向自己的右孩子。
重复第2步的判断。判断p存在或者栈s不为空即可继续。此时,虽然栈S是空的,但是P存在,所以继续。
因为P存在,所以将P压入栈S中,然后P指向自己的左孩子。
- 重复上面的操作即可得到最终的队列为:dbeafcg
#include
using namespace std;
//构建树的结构
typedef char BiElemType;
typedef struct BiTNode
{
BiElemType data;
BiTNode* lchild;//树的左孩子结点
BiTNode* rchild;//树的右孩子结点
}BiTNode,*BiTree;
//栈的相关数据结构
#define MaxSize 50
typedef BiTree ElemType;
typedef struct SqStack {
ElemType data[MaxSize];
int top;
};
/*
以下为栈的方法实现
*/
void InitStack(SqStack& S) {
S.top = -1;
}
bool Push(SqStack& S, ElemType e) {
if (S.top == MaxSize - 1) {
return false;
}
S.top++;
S.data[S.top] = e;
return true;
}
bool Pop(SqStack& S, ElemType& x) {
if (S.top == -1) {
return false;
}
x = S.data[S.top];
S.top--;
return true;
}
bool GetTop(SqStack S, ElemType& x) {
if (S.top == -1)
{
return false;
}
x = S.data[S.top];
return true;
}
bool StackEmpty(SqStack S) {
if (S.top == -1) {
return true;
}
return false;
}
//中序遍历非递归
void InOrder2(BiTree T) {//传入的参数是树根的地址
SqStack S;
InitStack(S);
BiTree p = T;//用一个遍历的变量p,先等于树根
while (p || !StackEmpty(S)) {
if (p) {
//不断压栈的过程找到了最左边的左孩子
Push(S, p);
p = p->lchild;
}
else
{
Pop(S, p);
putchar(p->data);
p = p->rchild;
}
}
}