数据结构——二叉树(链式存储)

        本文介绍二叉树的链式存储,即用一组离散的存储空间存储二叉树,相关操作包括了对二叉树的前序(先序)、中序、后序遍历,需要用到递归的算法思想进行操作,对于非线性结构,如果想对之进行操作,少不了对它进行遍历。话不多说,我们开始操作:

先对要用的数据宏定义一下(非必要):

#define TREE_TYPE char
#define EMPTY '#'
#define END '\0'

定义一下链式二叉树的数据项,大概了解一下二叉链的构成:

//设计二叉树结点
typedef struct TreeNode
{
	TREE_TYPE data;
	struct TreeNode *left;
	struct TreeNode *right;
}TreeNode;

下面用C语言函数写出二叉树链式存储的各种操作:

创建二叉树结点

//创建二叉树结点
TreeNode *create_tree_node(TREE_TYPE data)
{
	TreeNode *node=malloc(sizeof(TreeNode));
	node->data=data;
	node->left=NULL;
	node->right=NULL;
	return node;
}

TreeNode *_create(char **str)
{
	if(EMPTY==**str || END==**str) return NULL;
	TreeNode *node=create_tree_node(**str);
	*str+=1;
	node->left=_create(str);
	*str+=1;
	node->right=_create(str);
	return node;
}

创建二叉树

//创建二叉树
TreeNode *create_tree(char *str)
{
	_create(&str);
}

先序遍历

//先序
void preorder_tree(TreeNode *root)
{
	if(NULL==root) return;
	printf("%c ",root->data);
	preorder_tree(root->left);
	preorder_tree(root->right);
}

中序遍历

//中序
void midorder_tree(TreeNode *root)
{
	if(NULL==root) return;
	midorder_tree(root->left);
	printf("%c ",root->data);
	midorder_tree(root->right);	
}

后序遍历

//后序
void postorder_tree(TreeNode *root)
{	
	if(NULL==root) return;
	postorder_tree(root->left);
	postorder_tree(root->right);	
	printf("%c ",root->data);
}

树的高度

//树的高度
int high_tree(TreeNode *root)
{
	if(NULL==root) return 0;
	int lh=high_tree(root->left);
	int rh=high_tree(root->right);
	return lh>rh?lh+1:rh+1;
}

树的密度

//树的密度
int num_tree(TreeNode *root)
{
	if(NULL==root) return 0;
	return num_tree(root->left)+num_tree(root->right)+1;
}

求左子树

//求左子树
TreeNode *left_tree(TreeNode *root,TREE_TYPE data)
{
	if(NULL==root) return NULL;
	if(data==root->data&&root->left) return root->left;
	TreeNode *left=left_tree(root->left,data);
	TreeNode *right=left_tree(root->right,data);
	return left==NULL?right:left;
}

求右子树

//求右子树
TreeNode *right_tree(TreeNode *root,TREE_TYPE data)
{
	if(NULL==root) return NULL;
	if(data==root->data&&root->right) return root->right;
	TreeNode *left=right_tree(root->left,data);
	TreeNode *right=right_tree(root->right,data);
	return left==NULL?right:left;
}

求根节点

//求根结点
TreeNode *root_tree(TreeNode *root,TREE_TYPE data)
{
	if(NULL==root) return NULL;
	if(data==root->data) return root;
	TreeNode *left=root_tree(root->left,data);
	TreeNode *right=root_tree(root->right,data);
	return left==NULL?right:left;
}

插入

//插入
bool insert_tree(TreeNode *root,TREE_TYPE pdata,TREE_TYPE data)
{
	TreeNode *node=create_tree_node(data);
	if(NULL==root) return false;
	if(pdata==root->data)
	{
		if(NULL==root->left)
		{
			root->left=node;
			return true;
		}
		else if(NULL==root->right)
		{
			root->right=node;
			return true;
		}
		else return false;
	}
	if(insert_tree(root->left,pdata,data)) return true;
	if(insert_tree(root->right,pdata,data)) return true;
}

删除

//删除
bool del_tree(TreeNode *root,TREE_TYPE data)
{
	if(NULL==root) return false;
	if(root->left!=NULL&&data==root->left->data)
	{
		free(root->left->left);
		free(root->left->right);
		root->left=NULL;
		return true;
	}
	if(root->right!=NULL&&data==root->right->data)
	{
		free(root->right->left);
		free(root->right->right);
		root->right=NULL;
		return true;
	}
	if(del_tree(root->left,data)) return true;
	if(del_tree(root->right,data)) return true;
}

销毁

//销毁
void destroy_tree(TreeNode *root)
{
	del_tree(root,'G');	
	del_tree(root,'D');	
	del_tree(root,'C');	
	del_tree(root,'E');	
	del_tree(root,'F');	
	del_tree(root,'B');	
	del_tree(root,'A');
	free(root);
}

二叉树的链式存储大致运算就这些,下面我们可以调用函数测试一下:

int main(int argc,const char* argv[])
{
	TreeNode *root=create_tree("ACD#G###BF##E##");
	preorder_tree(root);
	printf("\n");
	midorder_tree(root);
	printf("\n");
	postorder_tree(root);
	printf("\n");
	printf("%d\n",high_tree(root));
	printf("%d\n",num_tree(root));
	TreeNode *left=left_tree(root,'B');
	printf("%c\n",left->data);
	TreeNode *right=right_tree(root,'D');
	printf("%c\n",right->data);
	if(insert_tree(root,'C','Z')) preorder_tree(root);
	printf("\n");
	TreeNode *r=root_tree(root,'D');
	printf("%c\n",r->data);
	if(del_tree(root,'Z')) preorder_tree(root);
	printf("\n");
	if(del_tree(root,'G')) preorder_tree(root);
	printf("\n");
	destroy_tree(root);
	preorder_tree(root);
	
	return 0;
}

over

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值