为什么前序遍历和中序遍历的关系相当于以前序序列入栈,中序序列出栈
时间: 2023-07-24 13:12:09 浏览: 108
前序遍历和中序遍历的关系可以通过栈来模拟。在前序遍历中,根节点首先被访问,然后是左子树,最后是右子树。而在中序遍历中,左子树首先被访问,然后是根节点,最后是右子树。
如果我们以前序序列入栈,并且按照前序遍历的顺序建立二叉树,那么每次入栈的节点都会成为其父节点的左子节点。而在中序序列中,当一个节点的左子树已经被访问完毕时,该节点才会被访问。
所以,我们可以通过模拟入栈和出栈的过程来实现前序和中序遍历之间的关系。当一个节点入栈后,我们需要不断地将其左子节点入栈,直到没有左子节点为止。然后我们开始出栈操作,每次出栈都意味着一个节点的左子树已经被访问完毕,我们可以访问该节点,并将其右子节点入栈。
通过这种方式,我们可以按照前序遍历的顺序依次访问二叉树的节点,并且在访问每个节点时,判断其在中序遍历中的位置,从而实现前序遍历和中序遍历之间的关系。
相关问题
可以将前序序列看作入栈,后序序列看作出栈吗
是的,你可以将前序序列看作入栈的过程,后序序列看作出栈的过程。这种方法被称为前序遍历的逆序遍历,也可以用来实现后序遍历。
具体的步骤如下:
1. 将前序序列的最后一个节点作为根节点,并将其入栈。
2. 循环执行以下操作,直到栈为空:
- 弹出栈顶节点,并将该节点加入后序序列。
- 若该节点存在左子树,则将左子树的根节点入栈。
- 若该节点存在右子树,则将右子树的根节点入栈。
通过这种方式,可以得到后序遍历的逆序结果。
需要注意的是,这里的后序序列是逆序输出的,即先访问右子树,再访问左子树,最后访问根节点。如果需要得到正常的后序序列,只需将最终得到的逆序序列进行反转即可。
这种方法同样利用了栈的后进先出特性,通过不断入栈和出栈操作,可以按照后序遍历的顺序访问二叉树的所有节点。
c语言编程完成通过二叉树的顺序存储输入,创建二叉链树,利用上面创建的二叉链树,采用递归形式实现前序遍历和非递归形式完成中序遍历,并输出信息
以下是C语言代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
// 定义二叉树结构体
typedef struct node{
char data;
struct node *lchild, *rchild;
} BiTNode;
// 定义栈结构体
typedef struct stack{
BiTNode *data[MAXSIZE];
int top;
} Stack;
// 初始化栈
void initStack(Stack *s){
s->top = -1;
}
// 判断栈是否为空
int isEmptyStack(Stack *s){
if(s->top == -1){
return 1;
}
return 0;
}
// 判断栈是否已满
int isFullStack(Stack *s){
if(s->top == MAXSIZE - 1){
return 1;
}
return 0;
}
// 入栈
int push(Stack *s, BiTNode *node){
if(isFullStack(s)){
return 0;
}
s->top ++;
s->data[s->top] = node;
return 1;
}
// 出栈
int pop(Stack *s, BiTNode **node){
if(isEmptyStack(s)){
return 0;
}
*node = s->data[s->top];
s->top --;
return 1;
}
// 创建二叉链表
void createBiTree(BiTNode **root){
char ch;
scanf("%c", &ch);
if(ch == '#'){
*root = NULL;
}else{
*root = (BiTNode*)malloc(sizeof(BiTNode));
(*root)->data = ch;
createBiTree(&((*root)->lchild));
createBiTree(&((*root)->rchild));
}
}
// 递归实现前序遍历
void preOrder(BiTNode *root){
if(root){
printf("%c ", root->data);
preOrder(root->lchild);
preOrder(root->rchild);
}
}
// 非递归实现中序遍历
void inOrder(BiTNode *root){
Stack s;
initStack(&s);
BiTNode *p = root;
while(p || !isEmptyStack(&s)){
// 将左子树依次入栈
while(p){
push(&s, p);
p = p->lchild;
}
// 左子树全部入栈后,开始出栈,出栈元素即为中序遍历顺序
if(!isEmptyStack(&s)){
pop(&s, &p);
printf("%c ", p->data);
// 将右子树入栈
p = p->rchild;
}
}
}
int main(){
BiTNode *root = NULL;
printf("请输入二叉树的顺序存储序列,其中用#表示空节点:\n");
createBiTree(&root);
printf("递归实现前序遍历结果为:");
preOrder(root);
printf("\n非递归实现中序遍历结果为:");
inOrder(root);
return 0;
}
```
运行结果为:
```
请输入二叉树的顺序存储序列,其中用#表示空节点:
AB##C##
递归实现前序遍历结果为:A B C
非递归实现中序遍历结果为:B A C
```