程序实现二叉树的结构及其操作

1、完全二叉树的存储可以使用一维数组进行存储。因为每个节点 i 的左儿子为 i*2,右儿子为 i*2 + 1;每个节点 i 的双亲为 i / 2;

2、链式存储结构

(1):二叉链表结构,结点由 结点元素和两个分别指向左、右子树的指针组成;

struct ChainTwo

{

DATA data;

struct ChainTwo *left;

struct ChainTwo *right; 

};

(2):三叉链表结构,结点由 结点元素和两个分别指向左、右子树和父结点的指针组成;

  struct ChainThree

{

DATA data;

struct ChainThree *left;

struct ChainThree *right;

struct ChainThree *parent;

};

#include <stdio.h>
#include <stdlib.h>
#define QUEUE_MAXSIZE 50
typedef char DATA;
//定义二叉链式结构
typedef struct ChainTree
{
	DATA data;
	struct ChainTree *left;
	struct ChainTree *right;
}ChainBinTree;
//初始化二叉树
ChainBinTree * BinTreeInit(ChainBinTree *node)
{
	if (node != NULL)
		return node;
	else
		return NULL;
}

/************************************************************************
函数名称:BinTreeAddNode
函数功能:添加结点到二叉树
函数参数:bt为父结点,node为子结点,n=1表示添加左子树,n=2表示添加右子树
函数返回:成功返回1,失败返回0
************************************************************************/
int BinTreeAddNode(ChainBinTree *bt, ChainBinTree *node, int n)
{
	if (bt == NULL)
	{
		printf("父结点不存在,请先设置父结点!\n");
		return 0;
	}
	switch(n)
	{
	case 1: //添加到左结点
		if (bt->left)
		{
			printf("左子树不为空!\n");
			return 0;
		}
		else
			bt->left = node;
		break;
	case 2://添加到右结点
		if (bt->right)
		{
			printf("右子树不为空!\n");
			return 0;
		}
		else
			bt->right = node;
		break;
	default:
		printf("输入错误!\n");
		return 0;
	}
	return 1;
}
/************************************************************************
函数名称:BinTreeLeft
函数功能:返回结点的左子树
函数参数:bt为父结点
函数返回:返回值为结点的左子树
************************************************************************/
ChainBinTree * BinTreeLeft(ChainBinTree *bt)
{
	if (bt)
		return bt->left;
	else
		return NULL;
}
/************************************************************************
函数名称:BinTreeRight
函数功能:返回结点的右子树
函数参数:bt为父结点
函数返回:返回值为结点的右子树
************************************************************************/
ChainBinTree * BinTreeRight(ChainBinTree *bt)
{
	if (bt)
		return bt->right;
	else
		return NULL;
}
/************************************************************************
函数名称:BinTreeIsEmpty
函数功能:判断树是否为空
函数参数:bt为父结点
函数返回:返回0表示树非空,返回1表示是空树
************************************************************************/
int BinTreeIsEmpty(ChainBinTree *bt)
{
	if (bt)
		return 0;
	else
		return 1;
}
/************************************************************************
函数名称:BinTreeIsEmpty
函数功能:判断树是否为空
函数参数:bt为父结点
函数返回:返回0表示树非空,返回1表示是空树
************************************************************************/
int BinTreeDepth(ChainBinTree *bt)
{
	int dep1, dep2;
	if (bt == NULL)
		return 0;
	else
	{
		dep1 = BinTreeDepth(bt->left);//左子树深度,递归调用
		dep2 = BinTreeDepth(bt->right);//右子树深度,递归调用
		if (dep1 > dep2)
			return dep1 + 1;
		else
			return dep2 + 1;
	}
}
/************************************************************************
函数名称:BinTreeFind
函数功能:在树中查找某个数值等于data的结点
函数参数:bt为父结点, 数值为data
函数返回:若没有找到返回NULL,若找到返回该结点的指针
************************************************************************/
ChainBinTree *BinTreeFind(ChainBinTree *bt, DATA data)
{
	ChainBinTree *p;

	if (bt == NULL)
		return NULL;
	else
	{
		if (bt->data == data)
			return bt;
		else
		{
			if (p = BinTreeFind(bt->left, data))
				return p;
			else if (p = BinTreeFind(bt->right, data))
				return p;
			else
				return NULL;
		}
	}
}
/************************************************************************
函数名称:BinTreeClear
函数功能:清空二叉树,释放每个结点的内存,使树变为空树
函数参数:bt为父结点
函数返回:没有返回值
************************************************************************/
void BinTreeClear(ChainBinTree *bt)
{
	if (bt)
	{
		BinTreeClear(bt->left);
		BinTreeClear(bt->right);
		free(bt);
		bt = NULL;
	}
	return;
}
/************************************************************************
函数名称:oper
函数功能:输出结点的数据data
函数参数:bt为结点
函数返回:没有返回值
************************************************************************/
void oper(ChainBinTree *p)
{
	if (p)
	{
		printf("%c ", p->data);
	}
	
	return;
}
/************************************************************************
函数名称:BinTree_DLR
函数功能:先序遍历树(DLR,D表示树根,L表示左子树,R表示右子树)
函数参数:bt为父结点, oper表示处理结点数据的函数
函数返回:没有返回值
************************************************************************/
void BinTree_DLR(ChainBinTree *bt, void (*oper)(ChainBinTree *p))
{
	if (bt)
	{
		oper(bt);
		BinTree_DLR(bt->left, oper);
		BinTree_DLR(bt->right, oper);
	}
	return;
}
/************************************************************************
函数名称:BinTree_LDR
函数功能:中序遍历树(LDR,D表示树根,L表示左子树,R表示右子树)
函数参数:bt为父结点, oper表示处理结点数据的函数
函数返回:没有返回值
************************************************************************/
void BinTree_LDR(ChainBinTree *bt, void (*oper)(ChainBinTree *p))
{
	if (bt)
	{
		BinTree_LDR(bt->left, oper);
		oper(bt);
		BinTree_LDR(bt->right, oper);
	}
	return;
}
/************************************************************************
函数名称:BinTree_LRD
函数功能:后序遍历树(LRD,D表示树根,L表示左子树,R表示右子树)
函数参数:bt为父结点, oper表示处理结点数据的函数
函数返回:没有返回值
************************************************************************/
void BinTree_LRD(ChainBinTree *bt, void (*oper)(ChainBinTree *p))
{
	if (bt)
	{
		BinTree_LRD(bt->left, oper);
		BinTree_LRD(bt->right, oper);
		oper(bt);
	}
	return;
}
/************************************************************************
函数名称:BinTree_Level
函数功能:按层遍历树
函数参数:bt为父结点, oper表示处理结点数据的函数
函数返回:没有返回值
************************************************************************/
void BinTree_Level(ChainBinTree *bt, void (*oper)(ChainBinTree *p))
{
	ChainBinTree *p;
	ChainBinTree *q[QUEUE_MAXSIZE];
	int head  = 0, tail = 0;
	if (bt)
	{
		tail = (tail + 1) % QUEUE_MAXSIZE;
		q[tail] = bt;
	}

	while (head != tail)
	{
		head = (head + 1) % QUEUE_MAXSIZE;
		p = q[head];
		oper(p);
		if (p->left != NULL)
		{
			tail = (tail + 1) % QUEUE_MAXSIZE;
			q[tail] = p->left;
		}
		if (p->right != NULL)
		{
			tail = (tail + 1) % QUEUE_MAXSIZE;
			q[tail] = p->right;
		}
	}
	return;
}
/************************************************************************
函数名称:InitRoot
函数功能:创建二叉树的根
函数参数:bt为父结点, oper表示处理结点数据的函数
函数返回:没有返回值
************************************************************************/
ChainBinTree *InitRoot()
{
	ChainBinTree *node;
	if (node = (ChainBinTree *)malloc(sizeof(ChainBinTree)))
	{
		printf("\n输入根结点数据:");
		scanf("%s", &node->data);
		node->left = NULL;
		node->right = NULL;
		return node;
	}
	return NULL;
}
/************************************************************************
函数名称:AddNode
函数功能:向指定的结点添加子节点
函数参数:bt为根结点
函数返回:没有返回值
************************************************************************/
void AddNode(ChainBinTree *bt)
{
	ChainBinTree * node, *parent;
	DATA data;
	char select;
	if (node = (ChainBinTree *)malloc(sizeof(ChainBinTree)))
	{
		printf("\n输入二叉树结点数据:");
		fflush(stdin);//清空输入缓冲区
		scanf("%c", &node->data);
		node->left = NULL;
		node->right = NULL;
		printf("输入父结点数据:");
		fflush(stdin);
		scanf("%c", &data);
		parent = BinTreeFind(bt, data);
		if (!parent)
		{
			printf("未找到父结点!\n");
			free(node);
			return;
		}
		printf("1.添加到左子树\n2.添加到右子树\n");
		do
		{
			select = getchar();
			select = select - '0';
			if (select == 1 || select == 2)
				BinTreeAddNode(parent, node, select);
		}while(select != 1 && select != 2);

	}
	return;
}
/************************************************************************
函数名称:main
函数功能:测试树结构及其操作
函数参数:无
函数返回:0表示成功
************************************************************************/
int main()
{
	ChainBinTree *root = NULL;
	char select;
	//void (*oper1)();
	//oper1 = oper;
	
	do
	{
		system("cls");
		printf("1.设置二叉树根元素       2.添加二叉树结点\n");
		printf("3.先序遍历               4.中序遍历\n");
		printf("5.后序遍历               6.按层遍历\n");
		printf("7.二叉树深度             8.清空树\n");
		printf("0.退出\n");
		
		select = getchar();
		getchar();
		switch(select)
		{
		case '1':			
			root = InitRoot();
			getchar();
			getchar();
			break;
		case '2':
			AddNode(root);
			getchar();
			break;
		case '3':
			printf("\n先序遍历的结果:");
			BinTree_DLR(root, oper);
			printf("\n");
			getchar();
			break;
		case '4':
			printf("\n中序遍历的结果:");
			BinTree_LDR(root, oper);
			printf("\n");
			getchar();
			break;
		case '5':
			printf("\n后序遍历的结果:");
			BinTree_LRD(root, oper);
			printf("\n");
			getchar();
			break;
		case '6':
			printf("\n按层遍历的结果:");
			BinTree_Level(root, oper);
			printf("\n");
			getchar();
			break;
		case '7':
			printf("\n二叉树的深度为:%d\n", BinTreeDepth(root));
			getchar();
			break;
		case '8':
			BinTreeClear(root);
			root = NULL;
			break;
		case '0':
			break;
		default:
			break;
		}
	}while(select != '0');
	BinTreeClear(root);
	root = NULL;
	getchar();
	getchar();
	return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值