数据结构实验
二叉树实验
本次的实验分为三个文件组成
main.c BinaryTree.h BinaryTreeImpl.h
main.c
#include <stdio.h>
#include "BinaryTree.h"
#include "BinaryTreeImpl.h"
/**
实验三 树和二叉树的基本操作
实验目的:明确了解二叉树的链表存储结构;熟练掌握二叉树的先序遍历算法;通过本次实习加深对高级语言C语言的使用,
熟悉数组在C语言中的实现。
实验要求:
设计二叉链表类型
利用二叉链表实现以下的题目要求。
题目:
题一:利用扩展先序遍历序列建立一棵用二叉链表方式存储的二叉树,并对其进行先序序列、中序序列、后序序列的输出。
题二:统计当前二叉树中的叶子结点的数量。
题三:计算当前二叉树的深度。
题四:按凹入表形式打印二叉树结构
实验数据:
6 3 2 1 0 0 0 5 0 0 8 7 0 0 0
10m 11w 12m 13w 14m 0# 0# 0# 15m 0# 0# 16w 17m 0# 0# 0# 0# 0# 0#
遍历结果:
先序遍历输出:
6 3 2 1 5 8 7
中序遍历输出:
1 2 3 5 6 7 8
后序遍历输出:
1 2 5 3 7 8 6
*/
int main() {
// //暴力建树
// //建立树的节点
// Node n1;
// Node n2;
// Node n3;
// Node n4;
//
// n1.data = 5;
// n2.data = 6;
// n3.data = 7;
// n4.data = 8;
//
// /*
// * 树的关系建立
// */
//
// n1.left = &n2;
// n1.right = &n3;
// n2.left = &n4;
// n3.left = NULL;
// n3.right = NULL;
// n4.left = NULL;
// n4.right = NULL;
//
// //先序遍历
// preorder(&n1);
// puts("\n-------------------");
// //中序遍历
// inorder(&n1);
// puts("\n-------------------");
// postorder(&n1);
printf("请输入树的数据元素:\n");
Tree = PerInsertInitTree();
puts("先序遍历输出:");
preorder(Tree);
printf("\n");
puts("中序遍历输出:");
inorder(Tree);
printf("\n");
puts("后序遍历输出:");
postorder(Tree);
printf("\n");
puts("树的叶子数量为");
printf("%d\n", FenZhiCountLeaveNumber(Tree));
puts("树的深度为");
printf("%d\n", get_TreeDeep(Tree));
puts("凹入表打印的二叉树为:");
PrintBinaryTree(Tree, 0);
return 0;
}
BinaryTree.h
//
// Created by yuluo on 2021/11/5.
//
#ifndef DEMO09_BINARYTREE_H
#define DEMO09_BINARYTREE_H
typedef struct {
int id;
char sex;
}ElementData;
/* 构建二叉树的数据结构 */
typedef struct Node
{
ElementData data;
struct Node* left;
struct Node* right;
} Node, *binarytree;
/* 定义树 */
binarytree Tree;
/* 函数功能定义 */
//前序,后序,中序
void preorder(Node* node);
void inorder(Node* node);
void postorder(Node* node);
// 先序遍历方法建树
binarytree PerInsertInitTree();
//计算叶子节点数量
void PostorderCountLeaveNumber(binarytree binarytree1);
int FenZhiCountLeaveNumber(binarytree binarytree1);
//计算树的深度
int get_TreeDeep(binarytree tree);
//凹入表打印二叉树
void PrintBinaryTree(binarytree tree, int n);
//打印
void print(binarytree binarytree1);
#endif //DEMO09_BINTRAY_H
BinaryTreeImpl.h
//
// Created by yuluo on 2021/11/5.
//
#ifndef DEMO09_BINARYTREEIMPL_H
#define DEMO09_BINARYTREEIMPL_H
/**
* 二叉树的功能实现
*/
#include <malloc.h>
/**
* 二叉树的先序遍历
* 利用递归遍历树
*
* 先从根出发 --> 左 ---> 右
*
* @param node
*/
void preorder(Node* node)
{
if (node != NULL)
{
print(node);
//递归实现
preorder(node->left);
preorder(node->right);
}
}
/**
* 中序遍历
*
* 根 ---> 左 ---> 右
*
*/
void inorder(Node* node)
{
if (node != NULL)
{
inorder(node->left);
/*printf("%d\t", node->data);*/
print(node);
inorder(node->right);
}
}
/**
* 后序遍历
*
* 左 ---> 右 ---> 根
*
*/
void postorder(Node* node)
{
if (node != NULL)
{
postorder(node->left);
postorder(node->right);
/*printf("%d\t", node->data);*/
print(node);
}
}
/**
* 利用递归实现先序遍历建立二叉树
*
* 实验数据:
* 6 3 2 1 0 0 0 5 0 0 8 7 0 0 0 0
* @return 二叉树的节点
*/
binarytree PerInsertInitTree()
{
binarytree node;
ElementData insert;
scanf("%d%c", &insert.id, &insert.sex);
if (insert.id == 0 && insert.sex == '#')
{
node = NULL;
}
else
{
node = malloc(sizeof (Node));
node->data = insert;
node->left = PerInsertInitTree();
node->right = PerInsertInitTree();
}
return node;
}
/**
* 后序遍历统计叶子节点数目
* @param binarytree1
*/
void PostorderCountLeaveNumber(binarytree binarytree1)
{
int count;
if(binarytree1!=NULL)
{
PostorderCountLeaveNumber(binarytree1->left);
PostorderCountLeaveNumber(binarytree1->right);
if(binarytree1->left == NULL && binarytree1->right == NULL)
count ++;
}
}
/**
*
* 概念:分而治之,先分开求结果,再合并
* 先得到左子树的结果,再得到右子树的结果,然后将左子、右子树结果合并通常来说,
* 分治法的函数是有返回值的
* 定义:要做什么事情
* 拆分与合并问题:
* 结束条件。
*
* 分治法统计叶子节点数目
*
* 叶子值得是度为0的节点 即 1 5 7
*
* @param binarytree1 二叉树
* @return int 左右树的叶子个数
*/
int FenZhiCountLeaveNumber(binarytree binarytree1)
{
int count;
if (binarytree1 == NULL)
{
count = 0;
}
else if (binarytree1->left == NULL && binarytree1->right == NULL)
count = 1;
else
//实现累加
count = FenZhiCountLeaveNumber(binarytree1->left) +
FenZhiCountLeaveNumber(binarytree1->right);
return count;
}
/**
* 计算树的深度
* 运用递归
* 一棵树的两边,左边和右边的树那个大
* 大的就是分支的深度,再加根的深度,就是树的深度
* @param tree
*/
int get_TreeDeep(binarytree tree)
{
/* 递归出口 */
if (tree == NULL)
{
return 0;
}
else
{
int left_deep = get_TreeDeep(tree->left);
int right_deep = get_TreeDeep(tree->right);
int deep_max = left_deep;
if (right_deep > deep_max)
{
deep_max = right_deep;
}
return deep_max + 1;
}
}
/**
* 递归打印二叉树
* @param tree
*/
void PrintBinaryTree(binarytree tree, int n)
{
if (tree != NULL)
{
for (int i = 0; i < n; i ++) {
printf("\t");
}
printf("%d %c \n", tree->data.id, tree->data.sex);
PrintBinaryTree(tree->left,n+1);
PrintBinaryTree(tree->right,n+1);
}
}
void print(binarytree binarytree1)
{
printf("学生的id: %d 学生的性别: %c ",
binarytree1->data.id, binarytree1->data.sex);
}
#endif //DEMO09_BIZARRELY_H
运行结果演示
运行测试数据: 10m 11w 12m 13w 14m 0# 0# 0# 15m 0# 0# 16w 17m 0# 0# 0# 0# 0# 0#
请输入树的数据元素:
10m 11w 12m 13w 14m 0# 0# 0# 15m 0# 0# 16w 17m 0# 0# 0# 0# 0# 0#
先序遍历输出:
学生的id: 10 学生的性别: m 学生的id: 11 学生的性别: w 学生的id: 12 学生的性别: m 学生的id: 13 学生的性别: w 学生的id: 14 学生的性别: m 学生的id: 15 学生的性别: m 学生的id: 16 学生的性别: w 学生的id: 17 学生的性别: m
中序遍历输出:
学生的id: 14 学生的性别: m 学生的id: 13 学生的性别: w 学生的id: 12 学生的性别: m 学生的id: 15 学生的性别: m 学生的id: 11 学生的性别: w 学生的id: 17 学生的性别: m 学生的id: 16 学生的性别: w 学生的id: 10 学生的性别: m
后序遍历输出:
学生的id: 14 学生的性别: m 学生的id: 13 学生的性别: w 学生的id: 15 学生的性别: m 学生的id: 12 学生的性别: m 学生的id: 17 学生的性别: m 学生的id: 16 学生的性别: w 学生的id: 11 学生的性别: w 学生的id: 10 学生的性别: m
树的叶子数量为
3
树的深度为
5
凹入表打印的二叉树为:
10 m
11 w
12 m
13 w
14 m
15 m
16 w
17 m
Process finished with exit code 0