二叉树的算法实现

Posted 午饭要阳光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的算法实现相关的知识,希望对你有一定的参考价值。

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

以上是关于二叉树的算法实现的主要内容,如果未能解决你的问题,请参考以下文章

二叉树遍历

二叉树的层次遍历

C语言 求二叉树根节点到叶子节点的路径

给出二叉树的先序和中序遍历,给出后序遍历

二叉树区分左右

PTA 二叉树的层次遍历