写完作业后记得给我点个赞呗~
目录
答案代码总览
我修改了题目结构体的定义,以符合我的编程习惯
// Created by Mr.Chen on 2023/10/14.
#include <stdio.h>
#include <stdlib.h>
typedef char DataType;
//定义顺序存储结构
typedef struct node
{
int maxNum; //最多可存储元素的个数
int n; //当前元素个数
DataType* data; //存储元素的数组
}node;
typedef node* seqBiTree;
/*辅助功能:逐个输出顺序表的元素,元素之间以空格为界*/
void printTree(seqBiTree T)
{
for (int i = 0; i < T->n ; ++i)
{
if (T->data[i] == '#')
putchar(' '); //答案格式如此,没办法
else
{
putchar(T->data[i]);
}
//元素之间以空格为界
putchar(' ');
}
}
/*第一关
* 形参m: 顺序表的最多可存储元素的个数
* 返回值:顺序存储的二叉树
*/
seqBiTree createSeqTree(int m)
{
//按层次遍历的顺序输入二叉树中的结点元素值,依顺序存储各结点元素。
//题目已经给好了层序遍历的顺序,我们只需要按部就班地读入即可
//定义并创建一个顺序二叉树
seqBiTree T = (seqBiTree) malloc(sizeof(struct node));
//初始化T,并为数组分配存储空间
T->maxNum = m;
T->n = 0;
T->data = (DataType*) malloc(sizeof (DataType) * m);
//读入元素
int i = 0;
DataType ch = getchar();
while (ch != '\n')
{
T->data[T->n ] = ch;
T->n ++;
ch = getchar();
}
return T;
}
/*第二关,返回二叉树的根结点的值,若二叉树为空,则返回#*/
char root(seqBiTree T)
{
if(T->n == 0)
return '#'; //当前元素个数为0即二叉树为空
else
return T->data[0]; //第一个元素即是根节点的值
}
/*第二关,求二叉树T中指定结点ch的双亲结点,返回值是双亲结点的下标,若双亲不存在,则返回-1*/
int parent(seqBiTree T ,char ch)
{
for (int i = 0; i < T->n ; ++i)
{
//遍历数组,找结点ch
if (T->data[i] == ch)
{
/*完全二叉树的性质:对任意下标为i的结点,
若i = 0,则它为根结点,没有父结点(没有双亲)
若i > 0,则它的父节点下标为(i-1)/2 */
if (i == 0)
return -1;
else
return (i - 1) / 2;
}
}
//树为空(T->n ==0)||结点ch不存在
return -1;
}
/*第二关,求二叉树T中指定结点ch的左孩子的下标,若左孩子不存在,则返回-1*/
int leftChild(seqBiTree T, char ch) {
for (int i = 0; i < T->n ; ++i) {
//遍历数组,找结点ch
if (T->data[i] == ch) {
/*完全二叉树的性质:对任意下标为i的结点(从0到n-1进行编号),
若2i + 1 <= n - 1,则它的左结点下标为2i + 1
否则它没有左结点*/
//将‘#’纳入后,T可视为完全二叉树;但返回下标时要排除'#'.
if ((2*i + 1) <= T->n - 1 && T->data[2*i+1] != '#')
return 2*i + 1;
else
return -1;
}
}
//树为空(T->n ==0)||结点ch不存在
return -1;
}
/*第二关,求二叉树T中指定结点ch的右孩子的下标,若右孩子不存在,则返回-1*/
int rightChild(seqBiTree T, char ch) {
for (int i = 0; i < T->n ; ++i) {
//遍历数组,找结点ch
if (T->data[i] == ch) {
/*完全二叉树的性质:对任意下标为i的结点(从0到n-1进行编号),
若2i + 2 <= n - 1,则它的右结点下标为2i + 2
否则它没有右结点 */
if ((2*i + 2) <= T->n - 1 && T->data[2*i+2] != '#')
return 2*i + 2;
else
return -1;
}
}
//树为空(T->n ==0)||结点ch不存在
return -1;
}
/*第三关:层序遍历二叉树,输出遍历得到的结点,结点之间不需要空格*/
void levelOrder(seqBiTree T)
{
//输入时已经是层序遍历的顺序,所以按数组顺序输出即是层序遍历啦
for (int i = 0; i < T->n; ++i)
{
if(T->data[i] != '#')
putchar(T->data[i]);
}
}
/*第四关:先序遍历二叉树,输出遍历得到的结点,结点之间不需要空格
* 形参root: 二叉树的根所在的下标
*/
void preOrder(seqBiTree 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);
seqBiTree 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); //测评第四关时,把本行代码放开
return 0;
}
主函数
int main(void)
{
int m;//顺序表可存放最多的元素个数
scanf("%d", &m);
seqBiTree 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); //测评第四关时,把本行代码放开
return 0;
}
第1关:创建顺序结构的二叉树
本关任务:输入二叉树的结点的数据,创建一个顺序结构存储二叉树 二叉树的数据为字符类型,输入‘#’表示该结点为空.
/*辅助功能:逐个输出顺序表的元素,元素之间以空格为界*/
void printTree(seqBiTree T)
{
for (int i = 0; i < T->n ; ++i)
{
if (T->data[i] == '#')
putchar(' '); //答案格式如此,没办法
else
{
putchar(T->data[i]);
}
//元素之间以空格为界
putchar(' ');
}
}
/*第一关
* 形参m: 顺序表的最多可存储元素的个数
* 返回值:顺序存储的二叉树
*/
seqBiTree createSeqTree(int m)
{
//按层次遍历的顺序输入二叉树中的结点元素值,依顺序存储各结点元素。
//题目已经给好了层序遍历的顺序,我们只需要按部就班地读入即可
//定义并创建一个顺序二叉树
seqBiTree T = (seqBiTree) malloc(sizeof(struct node));
//初始化T,并为数组分配存储空间
T->maxNum = m;
T->n = 0;
T->data = (DataType*) malloc(sizeof (DataType) * m);
//读入元素
int i = 0;
DataType ch = getchar();
while (ch != '\n')
{
T->data[T->n ] = ch;
T->n ++;
ch = getchar();
}
return T;
}
第2关:二叉树基本操作
本关任务:完成函数,能分别求出某二叉树的根、某个结点的双亲、左孩子、右孩子
/*第二关,返回二叉树的根结点的值,若二叉树为空,则返回#*/
char root(seqBiTree T)
{
if(T->n == 0)
return '#'; //当前元素个数为0即二叉树为空
else
return T->data[0]; //第一个元素即是根节点的值
}
/*第二关,求二叉树T中指定结点ch的双亲结点,返回值是双亲结点的下标,若双亲不存在,则返回-1*/
int parent(seqBiTree T ,char ch)
{
for (int i = 0; i < T->n ; ++i)
{
//遍历数组,找结点ch
if (T->data[i] == ch)
{
/*完全二叉树的性质:对任意下标为i的结点,
若i = 0,则它为根结点,没有父结点(没有双亲)
若i > 0,则它的父节点下标为(i-1)/2 */
if (i == 0)
return -1;
else
return (i - 1) / 2;
}
}
//树为空(T->n ==0)||结点ch不存在
return -1;
}
/*第二关,求二叉树T中指定结点ch的左孩子的下标,若左孩子不存在,则返回-1*/
int leftChild(seqBiTree T, char ch) {
for (int i = 0; i < T->n ; ++i) {
//遍历数组,找结点ch
if (T->data[i] == ch) {
/*完全二叉树的性质:对任意下标为i的结点(从0到n-1进行编号),
若2i + 1 <= n - 1,则它的左结点下标为2i + 1
否则它没有左结点*/
//将‘#’纳入后,T可视为完全二叉树;但返回下标时要排除'#'.
if ((2*i + 1) <= T->n - 1 && T->data[2*i+1] != '#')
return 2*i + 1;
else
return -1;
}
}
//树为空(T->n ==0)||结点ch不存在
return -1;
}
/*第二关,求二叉树T中指定结点ch的右孩子的下标,若右孩子不存在,则返回-1*/
int rightChild(seqBiTree T, char ch) {
for (int i = 0; i < T->n ; ++i) {
//遍历数组,找结点ch
if (T->data[i] == ch) {
/*完全二叉树的性质:对任意下标为i的结点(从0到n-1进行编号),
若2i + 2 <= n - 1,则它的右结点下标为2i + 2
否则它没有右结点 */
if ((2*i + 2) <= T->n - 1 && T->data[2*i+2] != '#')
return 2*i + 2;
else
return -1;
}
}
//树为空(T->n ==0)||结点ch不存在
return -1;
}
第3关:二叉树的层序遍历
本关任务:完成二叉树的层序遍历算法
/*第三关:层序遍历二叉树,输出遍历得到的结点,结点之间不需要空格*/
void levelOrder(seqBiTree T)
{
//输入时已经是层序遍历的顺序,所以按数组顺序输出即是层序遍历啦
for (int i = 0; i < T->n; ++i)
{
if(T->data[i] != '#')
putchar(T->data[i]);
}
}
第4关:二叉树的先序遍历
本关任务:完成遍历二叉树的函数
/*第四关:先序遍历二叉树,输出遍历得到的结点,结点之间不需要空格
* 形参root: 二叉树的根所在的下标
*/
void preOrder(seqBiTree 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); //遍历右结点
}