二叉树遍历,此题的特点,只根据先序遍历即可确定一棵二叉树
题目分析:
(1)给出的字符串是先序遍历的,因此需要递归遍历其左孩子,再遍历其右孩子,因为用空格表示空树,因此这道题只需先序遍历即可建立二叉树;
(2)建立二叉树后按照常规中序遍历即可。
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *lchild;
struct node *rchild;
}node,*tree;
int pos = 0;
tree Create(char a[]){
tree root = (tree)malloc(sizeof(node));
root->data = a[pos++];
if(root->data!='#'){
root->lchild = Create(a);
root->rchild = Create(a);
return root;
}else{
return NULL;
}
}
void InOrder(tree T){
if(T == NULL){
return;
}else{
InOrder(T->lchild);
printf("%c ",T->data);
InOrder(T->rchild);
}
}
int main(){
int len;
char a[100];
tree T;
while(scanf("%s",a)!=EOF){
pos = 0;
T=Create(a);
InOrder(T);
}
}
代码分析:
(1)对字符串中的每一个字符一次判断时用到了a[pos++],pos从0开始,可以保证遍历到字符串中的每一个字符,而不需要用for循环
递归顺序:
步骤 | root->data的值 | 是否为# | 找其孩子结点 | pos的值 |
1 | a | 否 | 左 | 0 |
2 | b | 否 | 左 | 1 |
3 | c | 否 | 左 | 2 |
4 | # | 是 | 返回3,找右孩子结点 | 3 |
5 | # | 是 | 返回2,找其右孩子结点 | 4 |
6 | d | 否 | 左 | 5 |
7 | e | 否 | 左 | 6 |
8 | # | 是 | 返回7,找其右孩子结点 | 7 |
9 | g | 否 | 左 | 8 |
10 | # | 是 | 返回9,找其右孩子结点 | 9 |
11 | # | 是 | 返回6,找其右孩子结点 | 10 |
12 | f | 否 | 左 | 11 |
13 | # | 是 | 返回12,找其右孩子结点 | 12 |
14 | # | 是 | 返回2,找其右孩子结点 | 13 |
15 | # | 是 | 返回1,找其右孩子结点 | 14 |
16 | return root |
(1)最开始T为空,调用函数Create(a),进入函数,开辟空间,此时根结点root的数值为a(a[0]=a),pos++;
(2)判断该数是否为#,若不是,寻找其左孩子,左孩子调用函数Create(a),此时root->data为b(a[1]=b),pos++;
(3)判断是否为#,不是,找其左孩子,左孩子调用函数Create(a),此时root->data为c(a[2]=c),pos++;
(4)判断是否为#,不是,继续寻找左孩子,调用Create(a),此时root->data为#(a[3]=#),pos++;
(5)判断是否为#,是,返回空,回到(3)处的函数调用,寻找其右孩子,右孩子调用函数Create(a),此时root->data为#(a[4]=#),pos++;
(6)判断是否为#,是,返回空,返回到(2)处的函数调用,寻找其右孩子,右孩子调用函数Create(a),此时root->data为d(a[5]=d),pos++;
(7)判断是否为#,不是,找其左孩子,左孩子调用函数Create(a),此时root->data为e(a[6]=e),pos++;
(8)判断是否为#,不是,找其左孩子,左孩子调用函数Create(a),此时root->data为#(a[7]=#),pos++;
(9)判断是否为#,是,返回空,返回到(7)处的函数调用,寻找其右孩子,右孩子调用函数Create(a),此时root->data为g(a[8]=g),pos++;
(10)判断是否为#,不是,找其左孩子,左孩子调用函数Create(a),此时root->data为#(a[9]=#),pos++;
(11)判断是否为#,是,返回空,返回到(9)处调用,寻找其右孩子,右孩子调用函数Create(a),此时root->data为#(a[10]=#),pos++;
(12)判断是否为#,是,返回空,返回到(6)处调用,寻找其右孩子,右孩子调用函数Create(a),此时root->data为f(a[11]=f),pos++;
(13)判断是否为#,不是,找其左孩子,左孩子调用函数Create(a),此时root->data为#(a[12]=#),pos++;
(14)判断是否为#,是,返回空,返回到(12)处调用,寻找其右孩子,右孩子调用函数Create(a),此时root->data为#(a[13]=#),pos++;
(15)判断是否为#,是,返回空,返回到(2)处调用,寻找其右孩子,右孩子调用函数Create(a),此时root->data为#(a[14]=#),pos++;
(16)返回root;