树和二叉树
第1关:二叉树的基本操作
任务描述
题目描述: 设计二叉树,能够对二叉树进行先序、中序、后序和层序遍历,遍历的操作为输出结点的值,设计主函数,输入一棵二叉树,按先序、中序、后序、层序的遍历顺序输出结点的值。二叉树的结点数不超过20。
测试说明
输入描述:输入数据只有一组, 二叉树的结点均为一个数字, 数据为 0 代表当前结点为空。输入结点的值按照二叉树的先序遍历顺序, 比如输入:
1 2 4 0 0 5 0 0 3 0 6 0 0
,0
表示空,输入的数字之间由空格分隔。
1
/ \
2 3
/ \ \
4 5 6
输出描述:输出先序、中序、后序和层序遍历二叉树得到的序列,各占一行,同一行的数字之间由空格分隔。
输入样例:
1 2 4 0 0 5 0 0 3 0 6 0 0
输出样例:
1 2 4 5 3 6
4 2 5 1 3 6
4 5 2 6 3 1
1 2 3 4 5 6
代码
#include <stdio.h>
#include <stdlib.h>
struct BiNode {
int data;
struct BiNode *lchild, *rchild;
};
struct BiTree {
struct BiNode *root;
};
void PreOrder(struct BiNode *bt) {
//TODO:前序遍历递归算法
//=========begin========
if (bt == NULL)
{
return;
}
else
{
printf("%d ", bt->data);
PreOrder(bt->lchild);
PreOrder(bt->rchild);
}
//==========end==========
}
void InOrder(struct BiNode *bt) {
//TODO:中序遍历递归算法
//=========begin========
if (bt == NULL)
{
return;
}
else
{
InOrder(bt->lchild);
printf("%d ", bt->data);
InOrder(bt->rchild);
}
//==========end==========
}
void PostOrder(struct BiNode *bt) {
//TODO:后序遍历递归算法
//=========begin========
if (bt == NULL)
{
return;
}
else
{
PostOrder(bt->lchild);
PostOrder(bt->rchild);
printf("%d ", bt->data);
}
//==========end==========
}
void LevelOrder(struct BiNode *root) {
//TODO:层次序遍历
//=========begin========
int front = -1, rear = -1;
struct BiNode *q;
struct BiNode *Q[30];
if (root == NULL)
{
return;
}
Q[++rear] = root;
while (front != rear)
{
q = Q[++front];
printf("%d ", q->data);
if (q->lchild != NULL)
{
Q[++rear] = q->lchild;
}
if (q->rchild != NULL)
{
Q[++rear] = q->rchild;
}
}
//==========end==========
}
struct BiNode *Create(struct BiNode *bt) {
//TODO:前序建立二叉树
//=========begin========
int num;
scanf(" %d", &num);
if (num == 0)
{
bt = NULL;
}
else
{
bt = (struct BiNode*)malloc(sizeof(struct BiNode));
bt->data = num;
bt->lchild = Create(bt->lchild);
bt->rchild = Create(bt->rchild);
}
return bt;
//==========end==========
}
void Release(struct BiNode *bt) {
//TODO:销毁二叉树
//=========begin========
if (bt != NULL)
{
Release(bt->lchild);
Release(bt->rchild);
free(bt);
}
//==========end==========
}
int main() {
struct BiTree b;
b.root = Create(b.root);
PreOrder(b.root);
printf("\n");
InOrder(b.root);
printf("\n");
PostOrder(b.root);
printf("\n");
LevelOrder(b.root);
Release(b.root);
return 0;
}
第2关:输出二叉树后序遍历的逆序
任务描述
题目描述: 采用先序法建立一棵二叉树,设计输出二叉树后序遍历的逆序,二叉树的数据域类型为字符型,扩展二叉树的叶子结点用‘
#
’表示,要求可以输出多棵二叉树的后序遍历逆序,当二叉树为空时程序结束。
测试说明
输入描述:循环输入多棵扩展二叉树的先序遍历序列,每棵树占一行,以回车结束,每棵二叉树中结点之间以空格隔开
输出描述:输出各二叉树后序遍历逆序,每次输出后面都换行,当二叉树为空时,输出“
NULL
”,程序结束。
输入样例:
A B # # C D # E # F # # G H # I K # # # #
A B D H # # I # # E J # # K # # C F L # # M # # G N # # O # #
#
输出样例:
A C G H I K D E F B
A C G O N F M L B E K J D I H
NULL
代码
#include <stdio.h>
#include <stdlib.h>
struct BiNode {
char data;
struct BiNode *lchild, *rchild;
};
struct BiTree {
struct BiNode *root;
};
struct Stack{
char data[100];
int top;
};
void Init(struct Stack *s)
{
s->top = -1;
}
void Push(struct Stack *s, char x)
{
s->data[++s->top] = x;
}
char Pop(struct Stack *s)
{
return s->data[s->top--];
}
void Print(struct Stack *s)
{
while (s->top != -1)
{
printf("%c ", Pop(s));
}
}
struct BiNode *Create(struct BiNode *bt) {
char ch;
scanf("%c ", &ch);
if (ch == '#')
bt = NULL;
else {
bt = (struct BiNode *)malloc(sizeof(struct BiNode));
bt->data = ch;
bt->lchild = Create(bt->lchild);
bt->rchild = Create(bt->rchild);
}
return bt;
}
void RePreOrder(struct BiNode *bt, struct Stack *s) {
//ToDo 递归输出二叉树后序遍历的逆序
//========begin======
if (bt == NULL)
{
return;
}
else
{
RePreOrder(bt->lchild, s);
RePreOrder(bt->rchild, s);
Push(s, bt->data);
}
//=========end=======
}
int Empty(struct BiTree *tree) {
//ToDo 判断是否为空
//========begin======
if (tree->root == NULL)
{
return 1;
}
else
{
return 0;
}
//=========end=======
}
int main() {
while (1) {
struct BiTree A;
//ToDo 设计主函数 以满足题意
//========begin======
struct Stack s;
A.root = Create(A.root);
Init(&s);
if (Empty(&A))
{
printf("NULL");
break;
}
RePreOrder(A.root, &s);
Print(&s);
printf("\n");
//=========end=======
}
return 0;
}
第3关:按中序输出二叉树中的分支结点
任务描述
题目描述: 二叉树的结点数据域是字符型,空结点用‘
#
’表示,按前序遍历建立二叉树,按中序输出二叉树中所有的分支结点,以空格隔开。
测试说明
输入描述: 输入二叉树的扩展二叉树的前序遍历序列。
输出描述: 按中序输出二叉树中所有的分支结点,以空格隔开,最后一个结点后面有空格,占一行。
输入样例:
AB#C##D##
输出样例:
B A
代码
#include <stdio.h>
#include <stdlib.h>
struct BiNode {
char data;
struct BiNode *lchild, *rchild;
};
struct BiTree {
struct BiNode *root;
};
struct BiNode *Create(struct BiNode *bt) {
char ch;
scanf(" %c", &ch);
if (ch == '#')
return NULL;
else {
bt = (struct BiNode *)malloc(sizeof(struct BiNode));
bt->data = ch;
bt->lchild = Create(bt->lchild);
bt->rchild = Create(bt->rchild);
}
return bt;
}
void InOrder(struct BiNode *bt) {
//ToDo 中序输出分支节点
//========begin=======
if (bt == NULL)
{
return;
}
else
{
InOrder(bt->lchild);
if (bt->lchild != NULL || bt->rchild != NULL)
{
printf("%c ", bt->data);
}
InOrder(bt->rchild);
}
//=========end========
}
int Empty(struct BiTree *tree) {
if (tree->root == NULL)
return 1;
else
return 0;
}
int main() {
struct BiTree btree;
//ToDo 设计主函数 以满足题目需求
//========begin=======
btree.root = Create(btree.root);
InOrder(btree.root);
//=========end========
return 0;
}
第4关:前序输出二叉树节点值与层次值
任务描述
本关任务:设二叉树采用二叉链表存放,该结点结构为
[lchild,data,level,rchild]
, 将二叉树中每个结点所在的层次值置入相应的level
域,并按前序序列顺序输出每个结点的值和level
值。
测试说明
输入样例1:
A B H # # # D # I E # # #
输出样例1:
A 1 B 2 H 3 D 2 I 3 E 4
输入样例2:
A B # # C # #
输出样例2:
A 1 B 2 C 2
输入样例3:
A B D # # E # # C # #
输出样例3:
A 1 B 2 D 3 E 3 C 2
代码
#include <stdio.h>
#include <stdlib.h>
struct BiNode {
char data;
int level;
struct BiNode *lchild, *rchild;
};
struct BiTree {
struct BiNode *root;
};
struct BiNode* Creat(struct BiNode* bt) {
char ch;
scanf(" %c", &ch);
if (ch == '#')
return NULL;
else {
bt = (struct BiNode*)malloc(sizeof(struct BiNode));
bt->data = ch;
bt->lchild = Creat(bt->lchild);
bt->rchild = Creat(bt->rchild);
}
return bt;
}
void level(struct BiNode* bt, int l) {
//TODO 将bt中level设置成当前层次值并打印、继续递归左右节点
//=======begin======
if (bt == NULL)
{
return;
}
else
{
printf("%c %d ", bt->data, l);
level(bt->lchild, ++l);
level(bt->rchild, l);
}
//========end=======
}
void preOrder(struct BiNode* bt) {
if (bt != NULL) {
preOrder(bt->lchild);
if ((bt->lchild == NULL && bt->rchild != NULL) || (bt->lchild != NULL && bt->rchild == NULL)) {
printf("%c ", bt->data);
}
preOrder(bt->rchild);
}
}
int Empty(struct BiTree* tree) {
if (tree->root == NULL)
return 1;
else
return 0;
}
int main() {
struct BiTree btree;
btree.root = Creat(btree.root);
level(btree.root, 1);
printf("\n");
return 0;
}
第5关:求二叉树中结点个数
任务描述
题目描述: 建立一棵二叉树,用二叉链表存储二叉树,计算二叉树中包含的结点个数。
测试说明
输入描述: 输入的数据只有一组,是一棵二叉树的先序遍历序列,结点的值为一个小写字母,
#
号表示空结点,如输入:a b d e # # f # # # c # #
,数据之间空一个格,得到的二叉树如下。输出描述: 输出二叉树的结点个数,空树输出
NULL
。
输入样例1:
a b c # # # d e # # f # #
输出样例1:6
输入样例2:
#
输出样例2:0
代码
#include <stdio.h>
#include <stdlib.h>
struct Binode {
char data;
struct Binode* lchild;
struct Binode* rchild;
};
struct Bitree {
struct Binode* root;
};
struct Binode* Creat(struct Binode* bt) {
char d;
scanf(" %c", &d);
if (d == '#')
bt = NULL;
else {
bt = (struct Binode*)malloc(sizeof(struct Binode));
bt->data = d;
bt->lchild = Creat(bt->lchild);
bt->rchild = Creat(bt->rchild);
}
return bt;
}
void Release(struct Binode* bt) {
if (bt != NULL) {
Release(bt->lchild);
Release(bt->rchild);
free(bt);
}
}
int Count(struct Binode* bt) {
//ToDo 计算节点个数
//=======begin======
if (bt == NULL)
{
return 0;
}
return Count(bt->lchild) + Count(bt->rchild) + 1;
//=======begin======
}
int main() {
//ToDo 设计主函数 以满足题意需求
//=======begin======
struct Bitree btree;
btree.root = Creat(btree.root);
printf("%d", Count(btree.root));
Release(btree.root);
//=======begin======
}
第6关:求二叉树叶子结点数
任务描述
题目描述: 二叉树结点的数据类型是字符型,按先序遍历建立二叉树,求叶子结点的个数。
测试说明
输入描述: 输入扩展二叉树的先序遍历序列,其中空字符为“
#
”,以空格隔开.输出描述: 输出叶子结点的个数.
输入样例:
A B D H # # # E # I # # C F J # # # G # #
输出样例:
4
代码
#include <stdio.h>
#include <stdlib.h>
struct BiNode {
char data;
struct BiNode* lchild;
struct BiNode* rchild;
};
int j = 0;
struct BiNode* Creat(struct BiNode* bt) {
//TODO:前序建立二叉树
//========begin=======
char ch;
scanf(" %c", &ch);
if (ch == '#')
{
bt = NULL;
}
else
{
bt = (struct BiNode*)malloc(sizeof(struct BiNode));
bt->data = ch;
bt->lchild = Creat(bt->lchild);
bt->rchild = Creat(bt->rchild);
}
return bt;
//=========end========
}
void Release(struct BiNode* bt) {
//TODO:后续销毁二叉树
//========begin=======
if (bt != NULL)
{
Release(bt->lchild);
Release(bt->rchild);
free(bt);
}
//=========end========
}
void Preorder(struct BiNode* bt) {
//TODO:前序遍历求叶子结点数
//========begin=======
if (bt == NULL)
{
return;
}
else
{
if (bt->lchild == NULL && bt->rchild == NULL)
{
j++;
}
Preorder(bt->lchild);
Preorder(bt->rchild);
}
//=========end========
}
int main() {
struct BiNode* root = NULL;
root = Creat(root);
Preorder(root);
printf("%d\n", j);
Release(root);
return 0;
}
第7关:求二叉树的深度
任务描述
题目描述 采用先序法建立一棵二叉树,设计求该二叉树的深度,二叉树的数据域类型为字符型,扩展二叉树的叶子结点用‘
#
’表示,要求可以求多棵二叉树的深度,当二叉树的深度为 0 时程序结束。
测试说明
输入描述: 循环输入多棵扩展二叉树的先序遍历序列,每棵树占一行,以回车结束,每棵二叉树中结点之间以空格隔开.
输出描述: 输出各二叉树的深度,每次输出后面都换行.
输入样例:
A B # # C D # E # F # # G H # I K # # # #
A B D H # # I # # E J # # K # # C F L # # M # # G N # # O # #
#
输出样例:
6
4
0
代码
#include <stdio.h>
#include <stdlib.h>
struct BiNode {
char data;
struct BiNode* lchild;
struct BiNode* rchild;
};
struct BiTree {
struct BiNode* root;
};
struct BiNode* Creat(struct BiNode* bt) {
char ch;
scanf(" %c", &ch);
if (ch == '#')
bt = NULL;
else {
bt = (struct BiNode*)malloc(sizeof(struct BiNode));
bt->data = ch;
bt->lchild = Creat(bt->lchild);
bt->rchild = Creat(bt->rchild);
}
return bt;
}
int Depth(struct BiNode* bt) {
//ToDo 递归求最大深度
//========BEGIN=======
if (bt == NULL)
{
return 0;
}
int left = Depth(bt->lchild);
int right = Depth(bt->rchild);
return left > right ? (left+1) : (right+1);
//=========END========
}
int main() {
while (1) {
struct BiTree A;
//ToDo 设计主函数 以满足题意
//========BEGIN=======
A.root = Creat(A.root);
printf("%d\n", Depth(A.root));
if (Depth(A.root) == 0)
{
break;
}
//=========END========
}
return 0;
}
第8关:二叉树交换左右子树
任务描述
本关任务:二叉树的结点数据域是字符型,空用‘
#
’表示,按前序遍历建立二叉树,交换二叉树中所有结点的左右子树,再前序遍历输出。
测试说明
输入样例1:
A B # # C # #
输出样例1:A C B
输入样例2:
A B H # # # D C # # I E # # #
输出样例2:A D I E C B H
输入样例3:
A B D # # E # # C # #
输出样例3:A C B E D
代码
#include <stdio.h>
#include <stdlib.h>
struct BiNode {
char data;
struct BiNode* lchild;
struct BiNode* rchild;
};
struct BiNode* Creat(struct BiNode* bt) {
char ch;
scanf(" %c", &ch);
if (ch == '#')
return NULL;
else {
bt = (struct BiNode*)malloc(sizeof(struct BiNode));
bt->data = ch;
bt->lchild = Creat(bt->lchild);
bt->rchild = Creat(bt->rchild);
}
return bt;
}
void Change(struct BiNode* bt) {
//TODO 交换左右子树 并将子树继续交换
//==========begin=========
if (bt == NULL)
{
return;
}
else
{
struct BiNode* temp = bt->lchild;
bt->lchild = bt->rchild;
bt->rchild = temp;
Change(bt->lchild);
Change(bt->rchild);
}
//===========end==========
}
void Print(struct BiNode* bt) {
printf("%c ", bt->data);
if (bt->lchild != NULL)
Print(bt->lchild);
if (bt->rchild != NULL)
Print(bt->rchild);
}
int Empty(struct BiNode* root) {
if (root == NULL)
return 1;
else
return 0;
}
int main() {
struct BiNode* root = NULL;
root = Creat(root);
if (Empty(root))
return 0;
Change(root);
Print(root);
return 0;
}
第9关:按中序遍历次序输出二叉树中度为1的结点
任务描述
本关任务:二叉树的结点数据域是字符型,空结点用‘
#
’表示,按前序遍历建立二叉树,按中序输出二叉树中度为 1 的结点。
测试说明
输入样例1:
A B H # # # D # I E # # #
输出样例1:B D I
输入样例2:
A # B # #
输出样例2:A
输入样例3:
A B C D # # # # #
输出样例3:C B A
代码
#include <stdio.h>
#include <stdlib.h>
struct BiNode {
char data;
struct BiNode *lchild;
struct BiNode *rchild;
};
typedef struct BiNode BiNode;
/*前序建立二叉树*/
BiNode *createBiTree() {
char ch;
scanf("%c ", &ch);
if (ch == '#') {
return NULL;
} else {
BiNode *node = (BiNode *) malloc(sizeof(BiNode));
node->data = ch;
node->lchild = createBiTree();
node->rchild = createBiTree();
return node;
}
}
void inOrderTraversal(BiNode *root) {
/*按中序输出二叉树中度为1的结点*/
/*=========begin========*/
if (root == NULL)
{
return;
}
else
{
inOrderTraversal(root->lchild);
if ((root->lchild == NULL && root->rchild != NULL) || (root->lchild != NULL && root->rchild == NULL))
{
printf("%c ", root->data);
}
inOrderTraversal(root->rchild);
}
/*==========end========*/
}
int main() {
BiNode *root = createBiTree(); /*前序建立二叉树*/
inOrderTraversal(root); /*中序输出度为1的结点*/
printf("\n");
return 0;
}