一、判断题
后序:左右根
中序:左根右
二、选择题
记住两点:
先序,后序遍历可以确定根节点。
中序遍历可以确定左子树和右子树。
做这种题就是,反复来回这两点
再来一题
还有这种题型
中序:左根右
后序取反:根右左
2-11
任何一棵二叉树的叶结点在先序、中序和后序遍历序列中的相对次序(2分)
A.发生改变
B.不发生改变
C.不能确定
D.以上都不对
先序遍历顺序是:M-L-R,后序遍历顺序是:L-R-M,可以看到,只有中间的结点(M)顺序变化了,左右结点相对位置是不变的;
那可以推断出,要满足题意的话“二叉树的先序序列与后序序列正好相反”,说明整个二叉树左子树或者右子树有一个没有(遍历就成了,先:M-L·;后:L-M 或者 先:M-R ;后:R-M )也就是必然是一条链。因此该二叉树的高度一定等于其节点数。
树的度:树中所有结点的度的最大值。
二叉树:是由n(n>=0)个结点构成的、每个结点最多只有两个子树的有序树。
满二叉树:所有分支结点都存在左子树和右子树,并且所有叶子结点都在同一层上。
完全二叉树:逻辑结构与满二叉树的前n个结点的逻辑结构相同。
1.只有一个结点,树的度为0.
2.不确定,(1)一个结点的二叉树度为0,(2)两个结点的二叉树度为1,(3)三个结点的二叉树可以为1或者2
3.二叉树是有序树,左右子树不可交换
4.正确
前6层总结点数为2^6-1=63,第7层结点数为24x2=48
因为是完全二叉树,第6层出现叶结点,所以该树最大有7层
总结点数63+48=111
三、编程题
6-1 统计二叉树度为2的结点个数 (10分)
本题要求实现一个函数,可统计二叉树中度为2的结点个数。
函数接口定义:
int NodeCount ( BiTree T);
T
是二叉树树根指针,函数NodeCount
返回二叉树中度为2的结点个数,若树为空,返回0。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef char ElemType;
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
BiTree Create();/* 细节在此不表 */
int NodeCount ( BiTree T);
int main()
{
BiTree T = Create();
printf("%d\n", NodeCount(T));
return 0;
}
/* 你的代码将被嵌在这里 */
输出样例(对于图中给出的树):
2
//思路:递归边界:树为空时,返回0;递归关系:先递归左子树,再递归右子树,每次遇到度为2的结点,count+1;
//注意:特殊情况为根结点只有左子树或右子树
int NodeCount ( BiTree T)
{
int n=0;
if(!T)
{
n=0;
}
else
{
if(T->lchild&&T->rchild)//左右子树存在(根节点度为2)
{
n++;
n+=NodeCount(T->lchild);
n+=NodeCount(T->rchild);
}
else//只有左子树或只有右子树(根节点度为0或1)
{
n+=NodeCount(T->lchild);
n+=NodeCount(T->rchild);
}
}
return n;
}
6-2 后序输出第i个结点 (6分)
本题要求实现对于给定的二叉树,打印后序序列中指定序号的结点。
函数接口定义:
void PrintNode(BiTree T);
T是二叉树树根指针,PrintNode
函数输出给定二叉树的后序序列中第n个结点,n为结点在后序序列中的序号,从1开始编号。
其中BinTree
结构定义如下:
typedef char ElemType;
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef char ElemType;
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
BiTree Create();/* 细节在此不表 */
void PrintNode(BiTree T);
int n;//要打印的结点的在先序序列中的序号
int main()
{
BiTree T = Create();
scanf("%d", &n);
printf("The %d-th node in postorder is: ", n);
PrintNode(T);
printf("\n");
return 0;
}
/* 你的代码将被嵌在这里 */
输出样例(对于图中给出的树,当输入的n为2时):
The 2-th node in postorder is: G
//思路://递归关系:遍历大规模二叉树归结为遍历左子树、右子树、根。左右子树的遍历需要递归,递归的次数即后序输出中结点的次序
//递归边界:空树直接返回
//注意:定义变量k来记录递归次数,每递归一次,k++
int k=0;
void PrintNode(BiTree T)
{
if(!T) return;
if(T)
{
if(T->lchild)
{
PrintNode(T->lchild);
}
if(T->rchild)
{
PrintNode(T->rchild);
}
//printf("%d",T->data);
if(++k==n)
{
printf("%c",T->data);
return;
}
}
}
7-1 根据后序和中序遍历输出先序遍历 (25分)
本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。
输入格式:
第一行给出正整数N(≤30),是树中结点的个数。随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。
输出格式:
在一行中输出Preorder: 以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。
输入样例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
输出样例:
Preorder: 4 1 3 2 6 5 7
//思路:采用递归的思想,从中序数组找根节点,中序数组中这个根节点左边的就是左子树,右边就是右子树,递归左右两部分然后就可得所有节点
//注意:递归边界:空树,递归过程中要求出子树的长度来确定根节点
//头文件包含
#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
//函数状态码定义
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define INFEASIBLE -2
typedef int Status;
//二叉链表存储结构定义
typedef int TElemType;
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
//创建二叉树各结点,输入0代表创建空树。
//采用递归的思想创建
//递归边界:空树如何创建呢:直接输入0;
//递归关系:非空树的创建问题,可以归结为先创建根节点,输入其数据域值;再创建左子树;最后创建右子树。左右子树递归即可完成创建!
Status CreateBiTree(BiTree &T){
TElemType e;
scanf("%d",&e);
if(e==0)T=NULL;
else{
T=(BiTree)malloc(sizeof(BiTNode));
if(!T)exit(OVERFLOW);
T->data=e;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
return OK;
}
BiTree createTree(int *InorderTree, int *PostOrderTree, int len)
{
if (len <= 0) return NULL;
else
{
BiTree T = (BiTNode*)malloc(sizeof(BiTNode));
T->data = PostOrderTree[len-1];//根据后序遍历确定根节点
int i;
for (i = 0; i < len; i++)
{
if (InorderTree[i] == PostOrderTree[len-1])//在中序遍历中找到根节点
break;
}
T->lchild = createTree(InorderTree, PostOrderTree, i);//构建左子树
T->rchild = createTree(InorderTree + i + 1, PostOrderTree + i, len - i - 1);//构建右子树
return T;
}
}
void print_preorderTree(BiTree T)
{
if (!T) return ;
else
{
printf(" %d", T->data);//先序输出
print_preorderTree(T->lchild);
print_preorderTree(T->rchild);
}
}
int main()
{
int n;
int InorderTree[110], PostOrderTree[110];
BiTree T;
scanf("%d", &n);
for(int i=0; i<n; i++){
scanf("%d", &PostOrderTree[i]); //后序遍历
}
for(int i=0; i<n; i++){
scanf("%d", &InorderTree[i]); //中序遍历
}
T = createTree(InorderTree, PostOrderTree, n);
printf("Preorder:");
print_preorderTree(T);
return 0;
}