二叉树的算法实现

#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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值