二叉树的应用
实现二叉树的先序、后序递归遍历算法、中序遍历、一种非递归中序遍历(栈)、层序遍历(队列)、求二叉树的深度
栈和队列自己写
#include<stdlib.h>
#include<malloc.h>
#include<stdio.h>
typedef struct TreeNode *Node;
//定义结构体
typedef struct TreeNode{//树的结构体
char Element;//tree值
Node left;//节点左子节点
Node right;//节点右子节点
}Tree;
typedef struct Queue{//队列的结构体
struct Queue *next;
Node root;
int num;
}Queue;
typedef struct{
Node head;//要装的元素类型
int top;//元素长度
int LSize;//空间大小
}Sqlist;
//全局变量
int nn=0;//计时器
//函数声明
void Print();//输出函数
void Creat_BinaryTree(Tree **root);//创建二叉树
void Preorder(Tree *root);//先序遍历输出
void Inorder_1(Tree *root);//第一种中序序遍历输出
void Inorder_2(Tree *root);//第二种中序遍历输出
void Postorder(Tree *root);//后序遍历输出
void Level(Tree *root);//层序遍历输出
int Tree_Deel(Tree *root);//数的深度输出
void Free(Tree **root);//退出前进行释放空间
Queue *start_Q();//生成链表队列
Queue *PopQueue(Queue *queue);//取出队列第一个的元素
void PushQueue(Queue *queue,Tree *root);//放入队列元素
void start_S(Sqlist &T);//生成顺序栈
void PushSqlist(Sqlist &T,Node root);//放入栈中元素
void PopSqlist(Sqlist &T); //取出栈顶元素
void Add(Sqlist &T);//防止初始化空间不够
//主函数
int main(){
bool T=true;//用来进行循环
bool TC=false;//用来判断是否初始化
int Tree_nums=0;//用来记录树的深度
Print();
int num=0;//x选择输入的序号
scanf("%d",&num);
fflush(stdin);//清理上次输入缓存
Tree *Head=NULL;
while(T){
if(((num==1||num==8)&&!TC)||TC)
{
switch(num){
case 1:
Creat_BinaryTree(&Head);
TC=true;
printf("创建成功!!!\n");
break;
case 2:
Preorder(Head);//先序遍历
printf("\n");
break;
case 3:
Inorder_1(Head);
printf("\n");
break;
case 4:
Inorder_2(Head);
printf("\n");
break;
case 5:
Postorder(Head);
printf("\n");
break;
case 6:
Level(Head);
break;
case 7:
Tree_nums=Tree_Deel(Head);
printf("%d\n",Tree_nums);
break;
case 8:
Free(&Head);
if(Head==NULL)
{
printf("退出成功\n");
return 0;
}
else
printf("退出之前空间释放不成功\n");
break;
default:
printf("你输入的数字不合法!!!\n");
break;
}
}
else{
printf("请先进行初始化创建\n");
}
Print();
scanf("%d",&num);
fflush(stdin);//清理上次输入缓存
}
return 0;
}
//函数体
Queue *start_Q()//队列开辟
{
Queue *queue=NULL;
queue=(Queue*)malloc(sizeof(Queue));
queue->next=NULL;
queue->num=0;
if(queue!=NULL)
return queue;
else
printf("队列初始化失败!\n");
}
void PushQueue(Queue *queue,Tree *root)//放出队列中元素
{
queue->num+=1;
while(queue->next!=NULL)
{
queue=queue->next;
}
queue->next=start_Q();
queue->next->root=root;
}
Queue *PopQueue(Queue *queue)// 取出队列中元素
{
Queue *root=NULL;
if(queue->next!=NULL)
{
queue->num-=1;
root=queue->next;
queue->next=queue->next->next;
return root;
}
}
void start_S(Sqlist &T)//生成栈
{
T.head=(Node)malloc(sizeof(Node*)*20);//生成加入20个Tree(Node*)的数组
if(T.head!=NULL){
T.top=0;
T.LSize=20;
}
}
void PushSqlist(Sqlist &T,Node root)//往栈中放入元素
{
if(T.top==T.LSize)
{
Add(T);
}
if(T.top<=T.LSize)
{
T.top++;
T.head[T.top]=*root;
}
}
void PopSqlist(Sqlist &T)//栈头指针往下移一位
{
T.top--;
}
void Add(Sqlist &T)//顺序栈空间不够
{
T.head=(Node)realloc(T.head,sizeof(Node*)*(T.LSize+20));
T.LSize+=20;
}
void Inorder_2(Tree *root)//第二种中序遍历输出 栈的方法输出
{
Sqlist T;
start_S(T);
while(root!=NULL||T.top!=0)
{
if(root!=NULL)
{
PushSqlist(T,root);//放入栈
root=root->left;
}
else{
printf("%c\t",T.head[T.top].Element);//输出元素
root=T.head[T.top].right;
PopSqlist(T);//栈的头指针往下走一个
}
}
printf("\t");
}
void Free(Tree **root)//退出前进行释放空间
{
if(*root==NULL)
{
return;
}
if(root!=NULL){
Free(&(*root)->left);//先序先找有节点
Free(&(*root)->right);//右节点结束换到左结点在检查右节点
free(*root);//输出下一个节点的值
*root=NULL;
}
}
int Tree_Deel(Tree *root)//数的深度输出
{
int Tree_num=0;
if(root==NULL)
{
return 0;
}
if(root!=NULL){
int lTree_num=Tree_Deel(root->left);//先序先找有节点
int rTree_num=Tree_Deel(root->right);//右节点结束换到左结点在检查右节点
if(lTree_num>=rTree_num)//比较左右子树的深度
Tree_num=lTree_num+1;
else
Tree_num=rTree_num+1;
}
return Tree_num;
}
void Level(Tree *root)//层序遍历输出 队列方法
{
Queue *queue;
queue=start_Q();
Tree *k;
PushQueue(queue,root);
while(queue->num!=0){
k=PopQueue(queue)->root;
printf("%c\t",k->Element);
if(k->left!=NULL)
PushQueue(queue,k->left);
if(k->right!=NULL)
PushQueue(queue,k->right);
}
printf("\n");
}
void Postorder(Tree *root)//后序遍历输出
{
if(root==NULL)
{
return;
}
if(root!=NULL){
Postorder(root->left);//先序先找有节点
Postorder(root->right);//右节点结束换到左结点在检查右节点
printf("%c\t",root->Element);//输出下一个节点的值
}
}
void Inorder_1(Tree *root)//第一种中序序遍历输出
{
if(root==NULL)
{
return;
}
if(root!=NULL){
Inorder_1(root->left);//先序先找有节点
printf("%c\t",root->Element);//输出下一个节点的值
Inorder_1(root->right);//右节点结束换到左结点在检查右节点
}
}
void Preorder(Tree *root)//先序遍历输出
{
if(root==NULL)
{
return;
}
if(root!=NULL){
printf("%c\t",root->Element);//输出下一个节点的值
Preorder(root->left);//先序先找有节点
Preorder(root->right);//右节点结束换到左结点在检查右节点
}
}
void Creat_BinaryTree(Tree **root)//创建二叉树使用先序遍历输入
{
if(*root==NULL)
{
(*root)=(Tree*)malloc(sizeof(Tree));
if((*root)!=NULL){
(*root)->left=NULL;
(*root)->right=NULL;
if(nn==0)
{
printf("输入根节点的符号:");
nn++;
}
scanf("%c",&(*root)->Element);
if((*root)->Element!='#')
{
Creat_BinaryTree(&(*root)->left);
Creat_BinaryTree(&(*root)->right);
}
else{
free(*root);
*root=NULL;
}
}
else
printf("初始化错误\n");
}
}
void Print(){
printf("************************************************************\n");
printf("**************1.创建二叉树**********************************\n");
printf("**************2.先序遍历二叉树******************************\n");
printf("**************3.中序遍历二叉树1*****************************\n");
printf("**************4.中序遍历二叉树2*****************************\n");
printf("**************5.后序遍历二叉树******************************\n");
printf("**************6.层序遍历二叉树******************************\n");
printf("**************7.求二叉树的深度******************************\n");
printf("**************8.退出****************************************\n");
printf("请输入选择:");
}