二叉树的基本操作与应用

1.二叉树的基本操作:

进行基本操作要调用的函数:

#include"BTree.h"

//申请一个节点
BTreeNode *BuyBTreeNode(DataType data)
{
	BTreeNode *NewNode = (BTreeNode *)malloc(sizeof(BTreeNode));
	if(NULL == NewNode)
	{
		assert(0);
	}
	NewNode->data = data;
	NewNode->left = NULL;
	NewNode->right = NULL;
	return NewNode;
}
//构建树
void CreatBTree(BTreeNode **cur, DataType *str, DataType invalid, int *index)
{
	BTreeNode *ret = NULL;
	assert(cur&&str);
	if(str[*index] && invalid != str[*index])
	{
		(*cur) = BuyBTreeNode(str[*index]);
		(*index)++;
		CreatBTree(&(*cur)->left, str, invalid , index);
		if(str[*index] != '\0')
		{
			(*index)++;
			CreatBTree(&(*cur)->right, str, invalid , index);
		}
	}
}
//拷贝树
void CpBTree(BTreeNode *cur, BTreeNode **ret)
{
	assert(ret);
	if(cur)
	{
		(*ret) = BuyBTreeNode(cur->data);
		CpBTree(cur->left, &(*ret)->left);
		CpBTree(cur->right, &(*ret)->right);
	}
}
//销毁
void Destroy(BTreeNode **cur)
{
	BTreeNode *ret = *cur;
	assert(cur);
	if(*cur)
	{
		Destroy(&ret->left);
		Destroy(&ret->right);
		free(ret);
		ret = NULL;
	}
}

(1)前序遍历:

思路:

递归思路:如果二叉树为空时,算法结束,否则递归循环下面的操作:

                           a.  遍历根节点。

                           b.  递归遍历根节点的左子数

                           c.  递归遍历根节点的右子树

//前序遍历
void Preorder(BTreeNode *cur)
{
	if(cur)
	{
		printf("%c",cur->data);
		Preorder(cur->left);
		Preorder(cur->right);
	}
}

(2)中序遍历

思路:

递归思路:如果二叉树为空时,算法结束,否则递归循环下面的操作:

                           a.  递归遍历根节点的左子数

                           b.  遍历根节点。

                           c.  递归遍历根节点的右子树

//中序
void Inorder(BTreeNode *cur)
{
	if(cur)
	{
		Inorder(cur->left);
		printf("%c",cur->data);
		Inorder(cur->right);
	}
}

(3)后序遍历

思路:

递归思路:如果二叉树为空时,算法结束,否则递归循环下面的操作:

                           a.  递归遍历根节点的左子数

                           b.  递归遍历根节点的右子树

                           c.  遍历根节点。

//后序
void Postorder(BTreeNode *cur)
{
	if(cur)
	{
		Postorder(cur->left);
		Postorder(cur->right);
		printf("%c",cur->data);
	}
}

(4)二叉树节点的个数

思路:左子树和右子树的个数之和然后+1(根节点的个数)

//求树的节点个数
int BTreeNum(BTreeNode *cur)
{
	if(cur == NULL)
		return 0;
	return BTreeNum(cur->left) + BTreeNum(cur->right) + 1;
}

(5)二叉树的高度

思路:如果根节点为空的话,直接返回0. 

          如果左右子树不为空的话,返回左右子树高度的最大的高度+1(根节点的高度)

//求树的高度
int BTreeHight(BTreeNode *cur)
{
	int lefthight = 0;
	int righthight = 0;
	if(NULL == cur)
		return 0;
	lefthight = BTreeHight(cur->left);
	righthight = BTreeHight(cur->right);

	return lefthight > righthight ? lefthight+1 : righthight+1;
}

(6)求二叉树中叶子节点的个数

思路:如果根节点为空的话,直接返回0;

          如果二叉树不为空的话,如果根节点的左右子树都为空的话,返回1.

          递归遍历左右子树,返回左右子树中的叶子节点之和。

//叶子节点
int BTree(BTreeNode *cur)
{
	if(NULL == cur)
		return 0;
	if(NULL == cur->left && NULL == cur->right)
		return 1;
	return BTree(cur->left)+BTree(cur->right);
}

(7)求二叉树的第K层的节点个数

思路:如果根节点为空的话,返回0.

           如果到达第K层的话,返回1。

           然后递归返回左右子树中第K层节点之和。

//求第k层的节点
int BTreeKnum(BTreeNode *cur, int K)
{
	if(NULL == cur)
		return 0;
	if(K == 1)
		return 1;
	return BTreeKnum(cur->left,K-1) + BTreeKnum(cur->right,K-1);
}

(8)获取一个节点的双亲节点

思路:如果根节点不存在的话,直接返回NULL

           如果要求根节点的双亲节点的话,直接返回NULL。

           如果根节点的左孩子或者时右孩子是要查找的节点,返回根节点

        递归遍历左子树,如果左子树找到双亲节点的话,就不用递归遍历右子树。如果左子树没有找到双亲节点的话,就递归遍历右子树。

//求一个节点的双亲节点
BTreeNode* ParentNode(BTreeNode *cur, DataType  data)
{
	BTreeNode *ret = NULL;
        if(cur == NULL)
            return NULL;
	if(cur->data == data)
		return NULL;
	if(cur->left->data == data|| cur->right->data == data)
		return cur;
	ret = ParentNode(cur->left, data);
	//如果左子数找到的话,就不用进右子树找了
	//如果左子数找不到的话,进入右子树找
	if(ret == NULL)
	   ret =  ParentNode(cur->right, data);
	return ret;
}

(9)获取一个节点的左孩子

思路:如果根节点不存在的话,直接返回NULL

           如果根节点是你要查找到的节点,直接返回根节点的左孩子。

           递归遍历左子树,如果左子树找到的话,就不用递归遍历右子树。如果左子树没有找到的话,就递归遍历右子树。

//求一个节点的左孩子
BTreeNode *LeftNode(BTreeNode *cur, DataType  data)
{
	BTreeNode *ret = NULL;
	if(NULL == cur)
		return NULL;
        if(cur->data == data)
	{
		return cur->left;
	}
	ret = LeftNode(cur->left, data);
		//如果左子数找到的话,就不用进右子树找了
	//如果左子数找不到的话,进入右子树找
	if(ret == NULL)
	   ret =  LeftNode(cur->right, data);
	return ret;
}

ÿ

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值