#ifndef __TREE_H__ //条件编译
#define __TREE_H__
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 1000
typedef int ElemType;
typedef struct Tree //树中结点信息的结构体
{
ElemType data;
struct Tree *lchild;
struct Tree *rchild;
}tree;
tree* tier_creat(tree *root); //层序创建树
tree* DLR_creat(tree *root); //先序创建树
tree* LDR_creat(tree *root); //中序创建树
tree* LRD_creat(tree *root); //后序创建树
void DLR(tree const *root); //先序遍历
void LDR(tree const *root); //中序遍历
void LRD(tree const *root); //后序遍历
int leaf_node(tree const *root); //求叶子结点个数
int tree_node(tree const *root); //树中结点个数
tree *search_node(tree const *root, ElemType x); //查找数中结点位置
int tree_deep(tree *root); //求树的深度
void output(tree const *root, void(*fun)(tree const *src)); //打印树
void init(tree *root);
#endif //__TREE_H__
#include"tree.h"
void judge_NULL(tree *p)
{
if (p==NULL)
{
perror("out of mermoy");
exit(EXIT_FAILURE);
}
}
tree* tier_creat(tree *root)
{
printf("层序创建树,以0表示虚结点,-1表示结束\n");
tree *s = NULL;
root = NULL;
ElemType n = 0;
tree *quene[MAXSIZE] = { 0 }; //创建一个队列
int fornt = 1;
int rear = 0;
scanf("%d", &n);
while (n != -1) //-1表示创建结束
{
s = NULL;
if (n != 0) //如果不是虚结点,则创建
{
s = (tree *)malloc(sizeof(tree));
judge_NULL(s);
s->data = n;
s->lchild = NULL;
s->rchild = NULL;
}
rear++;
quene[rear] = s; //在队尾处添加结点
if (rear == 1)
root = s; //将第一个结点作为树根
else
{
if (s&&quene[fornt]) //如果s和quene[fornt]不是虚结点
{
if (rear % 2 == 0)
quene[fornt]->lchild = s; //如果队尾是偶数,则s为左孩子
else
quene[fornt]->rchild = s; //如果队尾是奇数,则s为右孩子
}
if (rear % 2 == 1)
fornt++;
}
scanf("%d", &n);
}
return root;
}
tree* DLR_creat(tree *root)
{
printf("以0表示指针域为NULL\n");
root = NULL;
int n = 0;
scanf("%d", &n);
if (n == 0) //n==0递归结束
return NULL;
root = (tree *)malloc(sizeof(tree));
judge_NULL(root);
root->data = n;
root->lchild = DLR_creat(root->lchild);
root->rchild = DLR_creat(root->rchild);
return root;
}
tree* LDR_creat(tree *root)
{
printf("以0表示指针域为NULL\n");
root = NULL;
int n = 0;
scanf("%d", &n);
if (n == 0)
return NULL;
root = (tree *)malloc(sizeof(tree));
judge_NULL(root);
root->lchild =LDR_creat(root->lchild);
root->data = n;
root->rchild =LDR_creat(root->rchild);
return root;
}
tree* LRD_creat(tree *root)
{
printf("以0表示指针域为NULL\n");
root = NULL;
int n = 0;
scanf("%d", &n);
if (n == 0)
return NULL;
root = (tree *)malloc(sizeof(tree));
judge_NULL(root);
root->lchild = LRD_creat(root->lchild);
root->rchild = LRD_creat(root->rchild);
root->data = n;
return root;
}
void DLR(tree const *root)
{
if (root != NULL)
{
printf("%d ", root->data);
DLR(root->lchild);
DLR(root->rchild);
}
return;
}
void LDR(tree const *root)
{
if (root == NULL)
return;
LDR(root->lchild);
printf("%d ", root->data);
LDR(root->rchild);
}
void LRD(tree const *root)
{
if (root == NULL)
return;
LRD(root->lchild);
LRD(root->rchild);
printf("%d ", root->data);
}
int leaf_node(tree const *root) //叶子节点的个数
{
if (root == NULL) //根节点为空,则返回0
return 0;
if (root->lchild == NULL&&root->rchild == NULL) //如果是叶子节点,则返回1
return 1;
return leaf_node(root->lchild) + leaf_node(root->rchild);
}
int tree_node(tree const *root) //树中节点的个数
{
if (root == NULL)
return 0;
if (root->lchild == NULL&&root->rchild == NULL) //如果是叶子结点,则返回1
return 1;
return 1 + tree_node(root->lchild) + tree_node(root->rchild); //如果不是叶子结点,则加一,在递归
}
tree *search_node(tree const *root, ElemType x) //查找值为x的结点
{
if (root == NULL)
{
printf("树是空树\n");
return NULL;
}
tree *p = NULL;
if (root->data == x) //先判断是不是根节点
return (tree *)root;
if (root->lchild != NULL) //先寻找左孩子
{
p = search_node(root->lchild, x);
if (p != NULL) //如果找到则返回p
return p;
}
if (root->rchild != NULL)
return search_node(root->rchild, x);
return NULL; //没找到返回NULL
}
int tree_deep(tree *root) //树的深度
{
int left = 0;
int right = 0;
int deep = 0;
if (root)
{
left = tree_deep(root->lchild); //递归左孩子
right = tree_deep(root->rchild); //递归右孩子
deep = left > right ? left + 1 : right + 1;
}
return deep;
}
void output(tree const *root,void(*fun)(tree const *src)) //函数指针fun
{
if (root == NULL)
{
printf("树是空树\n");
return;
}
else
{
fun(root); //fun指向遍历方式
printf("\n");
}
}
void init(tree *root)
{
if (root == NULL)
return;
init(root->lchild);
init(root->rchild);
free(root);
root = NULL;
}
#include"tree.h"
tree* creat(tree *root, tree* (*p)(tree *root)) //使用函数指针p
{
root = p(root);
return root;
}
void menu()
{
printf("********************************** \n");
printf("*0.exit 1.creat \n");
printf("*2.tree_deep 3.search_node \n");
printf("*4.leaf_node 5.tree_node \n");
printf("*6.output 7.init \n");
printf("请输入:>");
}
void test()
{
tree *root = NULL;
void(*trav[3])(const tree *root); //函数指针数组,用来存放遍历方式
trav[0] = DLR;
trav[1] = LDR;
trav[2] = LRD;
tree* (*build[4])(tree *root); //函数指针数组,用来存放创建方式
build[0] = tier_creat;
build[1] = DLR_creat;
build[2] = LDR_creat;
build[3] = LRD_creat;
int ret = 0;
int i = 0;
int n = 0;
ElemType x = 0;
while (1)
{
menu();
scanf("%d", &n);
switch (n)
{
case 0:
exit(EXIT_FAILURE);
break;
case 1:
printf("************************\n");
printf("1.Tier_creat 2.DLR_creat\n");
printf("3.LDR_creat 4.LRD_creat\n\n");
while (1)
{
printf("请输入:>");
scanf("%d", &i);
if (i >= 1 && i <= 4)
break;
else
printf("输入无效\n");
}
root = creat(root, build[i-1]);
break;
case 2:
ret = tree_deep(root);
printf("树的深度:%d\n", ret);
break;
case 3:
printf("请输入要查找的结点:>");
scanf("%d", &x);
tree *p = search_node(root, x);
printf("结点位置:%#p\n", p);
break;
case 4:
ret = leaf_node(root);
printf("叶子结点的个数:%d\n", ret);
break;
case 5:
ret = tree_node(root);
printf("树中结点的个数:%d\n", ret);
break;
case 6:
printf("************************\n");
printf("1.DLR_creat 2.LRD_creat\n");
printf("3.LDR_creat \n\n");
while (1)
{
printf("请输入:>");
scanf("%d", &i);
if (i >= 1 && i <= 3)
break;
else
printf("输入无效\n");
}
output(root, trav[i - 1]);
break;
case 7:
init(root);
root = NULL;
printf("初始化成功\n");
break;
default:
printf("选择无效\n");
break;
}
}
}
int main()
{
test();
system("pause");
return 0;
}
二叉树的算法实现
最新推荐文章于 2022-05-27 19:15:51 发布