实验九 二叉树的建立及遍历应用
一、【实验目的】
1、掌握二叉树的建立方法
2、掌握二叉树遍历的基本方法(前序、中序、后序)
3、掌握递归二叉树遍历算法的应用
二、【实验内容】
1.构造一棵二叉树,树的形态如下图(亦见附件)所示,打印出先序遍历、中序遍历、后序遍历的遍历序列。
A
B F
C G
D E
2.选择一种遍历方式计算该树中叶子结点的个数,并打印出叶子结点。
3.编写一个层序遍历算法,利用队列结构按层次(同一层自左至右)输出二叉树中所有的结点。
三、【实验源代码】
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 256
typedef struct ElementType {
char name[MAX_SIZE];
}ElementType;
typedef struct TreeNode {
ElementType data; //数据域
struct TreeNode* left; //左子树
struct TreeNode* right; //右子树
}TreeNode;
typedef struct BinaryTree {
TreeNode* root; //二叉链的根结点
int length; //二叉链结点的总数
int depth; //深度
int diameter; //直径,从叶结点到叶结点的最长距离
}BinaryTree;
//链队结点
typedef struct qNode
{
TreeNode* data;
struct qNode* next;
}qNode;
typedef struct queue
{
qNode* front;
qNode* frear;
}queue;
void Initqueue(queue* queue);
void enqueue(queue* queue, TreeNode* data);
TreeNode* Popqueue(queue* queue);
int Isqueueempty(queue* queue);
void InitBinaryTree(BinaryTree* Tree);
int CreateBinaryTree(TreeNode* node);
//前
void PreOrderTraverse(TreeNode* node);
int CreateBinaryTree_Test(TreeNode* node);
//中
void InorderBinaryTree(TreeNode* node);
//非递归的中序遍历
void InoredeBinaryTree_Re(TreeNode* node);
//后序遍历
void PostorderBinaryTree(TreeNode* node);
//层序遍历
void ZorderBinarytree(TreeNode* node);
//打印叶子结点
void pre_ord(TreeNode* node);
//计算叶子结点个数
int count(TreeNode* node);
#define _CRT_SECURE_NO_WARNINGS 1
#include"BinaryTree.h"
void InitBinaryTree(BinaryTree* Tree)
{
Tree->length = 0;
Tree->depth = 0;
Tree->diameter = 0;
Tree->root = NULL;
}
int CreateBinaryTree(TreeNode* node)
{
if (!node) return 0;
char ch[MAX_SIZE];
scanf("%s", ch);
if (strcmp(ch, "#") == 0)
{
return 0;
}
strcpy(node->data.name, ch);
node->left = (TreeNode*)malloc(sizeof(TreeNode));
node->right = (TreeNode*)malloc(sizeof(TreeNode));
printf("%s的左节点:",ch);
if (CreateBinaryTree(node->left) == 0)
{
free(node->left);
node->left = NULL;
}
printf("%s的右节点:",ch);
if (CreateBinaryTree(node->right) == 0)
{
free(node->right);
node->right = NULL;
}
return 1;
}
//前
void PreOrderTraverse(TreeNode* node)
{
if (node)
{
printf("%s", node->data.name);
PreOrderTraverse(node->left);
PreOrderTraverse(node->right);
}
}
//中
void InorderBinaryTree(TreeNode* node)
{
if (node)
{
PreOrderTraverse(node->left);
printf("%s", node->data.name);
PreOrderTraverse(node->right);
}
}
//后
void PostorderBinaryTree(TreeNode* node)
{
if (node)
{
PostorderBinaryTree(node->left);
PostorderBinaryTree(node->right);
printf("%s", node->data.name);
}
}
void pre_ord(TreeNode* node)
{
if (node != NULL)
{
if (node->left == NULL && node->right == NULL)
{
printf("%s", node->data.name);
}
pre_ord(node->left);
pre_ord(node->right);
}
}
void Initqueue(queue* queue)
{
queue->front = (qNode*)malloc(sizeof(qNode));
queue->front->next = NULL;
queue->frear = queue->front;
}
void enqueue(queue* queue, TreeNode* data)
{
qNode* node = (qNode*)malloc(sizeof(qNode));
node->data = data;
node->next = NULL;
queue->frear->next = node;
queue->frear = node;
}
TreeNode* Popqueue(queue* queue)
{
TreeNode* data = NULL;//用来返回
qNode* node = queue->front->next;//便于释放内存
if (queue->frear == queue->front)
return data;
queue->front->next = node->next;
data = node->data;
if (queue->frear == node)
queue->frear = queue->front;
free(node);
return data;
}
int Isqueueempty(queue* queue)
{
return queue->front == queue->frear;
}
//层序遍历
void ZorderBinarytree(TreeNode* node)
{
queue queue;
Initqueue(&queue);
enqueue(&queue, node);
while (!Isqueueempty(&queue))
{
TreeNode* node = Popqueue(&queue);
printf("%s",node->data.name);
if (node->left != NULL)
enqueue(&queue, node->left);
if (node->right != NULL)
enqueue(&queue, node->right);
}
}
int count(TreeNode* node)
{
if (node == NULL)
return 0;
else if (node->left == NULL && node->right == NULL)
return 1;
else
return count(node->left) + count(node->right);
}
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "BinaryTree.h"
int main()
{
BinaryTree Tree;
InitBinaryTree(&Tree);
Tree.root = (TreeNode*)malloc(sizeof(TreeNode));
printf("请输入结点内容:");
CreateBinaryTree(Tree.root);
printf("叶子结点个数为:");
int cnt= count(Tree.root);
printf("%d", cnt);
printf("\n先序遍历结果:");
PreOrderTraverse(Tree.root);
printf("\n中序遍历结果:");
InorderBinaryTree(Tree.root);
printf("\n层序遍历结果:");
ZorderBinarytree(Tree.root);
printf("\n叶子结点为:");
pre_ord(Tree.root);
return 0;
}
四、【实验结果】
五、【实验心得】
巩固了遗忘的队列知识,了解了如何用队列解决层序遍历问题,和顺畅的用递归完成前中后序遍历,然后利用递归的特性,可以提示根结点来更好的输入左右结点,也更容易输入