二叉树应用

二叉树的应用
实现二叉树的先序、后序递归遍历算法、中序遍历、一种非递归中序遍历(栈)、层序遍历(队列)、求二叉树的深度
栈和队列自己写
在这里插入图片描述

#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("请输入选择:");
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值