第1关:创建顺序结构的二叉树
任务描述
本关任务:输入二叉树的结点的数据,创建一个顺序结构存储二叉树
二叉树的数据为字符类型,输入‘#’表示该结点为空.
测试用例输入的是如下二叉树,请思考一下,该如何输入该二叉树?
,
图一
提示:二叉树的顺序存储采用完全二叉树从上到下从左至右依次存放各个元素。因此,首先因该确定某具体二叉树按完全二叉树存储时输入的数据是什么。假设以’#'代表空树,则以图一的二叉树为例,其存储的树如图二所示:
,
图二
该二叉树的深度为3,因此分配存储空间,。对应的顺序存储结构数组如下:
,
所以,创建图一所示二叉树时,输入数据为:
15FCEADHG##B###M
其中,整数15代表顺序表的最多存储空间(最多可存储的结点个数)。
开始你的任务吧,祝你成功!
第2关:二叉树基本操作
任务描述
本关任务:完成函数,能分别求出某二叉树的根、某个结点的双亲、左孩子、右孩子
开始你的任务吧,祝你成功!
第3关:二叉树的层序遍历
任务描述
本关任务:完成二叉树的层序遍历算法
开始你的任务吧,祝你成功!
第4关:二叉树的先序遍历
任务描述
本关任务:完成遍历二叉树的函数
开始你的任务吧,祝你成功!
参考代码:
#include <stdio.h>
#include <stdlib.h>
/*
定义顺序存储结构
*/
typedef char DataType;
struct seqTree
{
int MAXNUM;
int n;//元素的个数
DataType* data;//数组起始地址
};
/*辅助功能:逐个输出顺序表的元素,元素之间以空格为界*/
void printTree(struct seqTree* T)
{
int i;
for (i = 0;i < T->n; i++){
if (T->data[i] == '#')
putchar(' ');
else
putchar(T->data[i]);
putchar(' ');
}
}
/*第一关
* 形参m: 顺序表的最多可存储元素的个数
* 返回值:顺序存储的二叉树
*/
struct seqTree* createSeqTree(int m)
{
//按层次遍历的顺序输入二叉树中的结点元素值,依顺序存储各结点元素。
char ch;
struct seqTree* bt = (struct seqTree*)malloc(sizeof(struct seqTree));
bt->data = (DataType*)malloc(sizeof(DataType) * m);
bt->n = 0;
bt->MAXNUM = m;
//依次输入数据
for (ch = getchar(); ch != '\n'; ch = getchar())
{
bt->data[bt->n] = ch;
bt->n++;
}
return bt;
}
/*第二关,返回二叉树的根结点的值,若二叉树为空,则返回#*/
char root(struct seqTree* T)
{
if (T->n == 0)
return '#';
else
return T->data[0];
}
/*第二关,求二叉树T中指定结点ch的双亲结点,返回值是双亲结点的下标,若双亲不存在,则返回-1*/
int parent(struct seqTree* T, char ch)
{
for (int i = 0; i < T->n; i++)
{
if (T->data[i] == ch)
if (i == 0)
return -1;
else
return (i - 1) / 2;
}
return -1;
}
/*第二关,求二叉树T中指定结点ch的左孩子的下标,若左孩子不存在,则返回-1*/
int leftChild(struct seqTree* T, char ch)
{
for (int i = 0; i < T->n; i++)
{
if (T->data[i] == ch)
if (2 * i + 1 < T->n && T->data[2 * i + 1] != '#')
return 2 * i + 1;
else
return -1;
}
return -1;
}
/*第二关,求二叉树T中指定结点ch的右孩子的下标,若右孩子不存在,则返回-1*/
int rightChild(struct seqTree* T, char ch)
{
for (int i = 0; i < T->n; i++)
{
if (T->data[i] == ch)
if (2 * i + 2 < T->n && T->data[2 * i + 2] != '#')
return 2 * i + 2;
else
return -1;
}
return -1;
}
/*第三关:层序遍历二叉树,输出遍历得到的结点,结点之间不需要空格*/
void levelOrder(struct seqTree* T)
{
for (int i = 0; i < T->n; i++)
if (T->data[i] != '#')
putchar(T->data[i]);
}
/*第四关:先序遍历二叉树,输出遍历得到的结点,结点之间不需要空格
* 形参root: 二叉树的根所在的下标
*/
void preOrder(struct seqTree* T, int root)
{
if (root >= T->n || T->data[root] == '#')
return;
putchar(T->data[root]);
preOrder(T, 2 * root + 1);
preOrder(T, 2 * root + 2);
}
int main(void)
{
int m;//顺序表可存放最多的元素个数
scanf("%d",&m);
struct seqTree *T = createSeqTree(m);
printTree(T); //测评第一关时,把本行代码放开
/*printf("%c\n",root(T)); // 测评第二关时,把该代码块放开
printf("%d\n",leftChild(T,'A'));
printf("%d\n",rightChild(T,'A'));
printf("%d\n",parent(T,'A'));*/
// levelOrder(T); //测评第三关时,把本行代码放开
//preOrder(T,0); //测评第四关时,把本行代码放开
}