数据结构——二叉树链式结构实现

目录

层序遍历

Tips

节点个数

二叉树叶子节点个数

 第K层节点个数

查找值为x的节点

二叉树的高度


很简单,对于二叉树链式结构,我们需要先建立一个二叉树——简单地用到链式结构

typedef int BTDataType;
typedef struct BinaryTreeNode//结构体嵌套结构体的代码
{
	BTDataType data;
	struct BinaryTreeNode* left;//左树
	struct BinaryTreeNode* right;//右树
}BTNode;

BTNode* BuyNode(BTDataType x)
{
    BTNode* node=(BTDataType*)malloc(sizeof(BTNode));//创建一个结构体大小的数据
    if(node==NULL)//判断是否创建成功
    {
        perror("malloc fail");
        return ;
    }
    node->data=x;//创建的数据存放x,两个子树初始化
    node->left=NULL;
    node->right=NULL;
    
    return node;
}

BTNode* CreatBinaryTree()//创建一个简单的树
{
	BTNode* node1 = BuyNode(1);
	BTNode* node2 = BuyNode(2);
	BTNode* node3 = BuyNode(3);
	BTNode* node4 = BuyNode(4);
	BTNode* node5 = BuyNode(5);
	BTNode* node6 = BuyNode(6);
	BTNode* node7 = BuyNode(7);

	node1->left = node2;
	node1->right = node4;
	node2->left = node3;
	node4->left = node5;
	node4->right = node6;
	node5->left = node7;

	return node1;
}

但这不是创建二叉树的真正方式

我们需要用到

层序遍历

设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。

可以粗略的约等于一个元素的逐个遍历,但是每个元素也会遍历到其指向的左右子树

——本质上也还能算是一个递归的实现

 为了实现层序遍历,我们需要用到队列—(先进后出的数据结构)

在队列中需要实现

1.元素的逐个放入

2.元素放入后的逐个读取,及其放入元素的左右子树

这样不仅实现根元素的读取,又能载入其左右子树,并且通过队列的删除,进行下一个元素的数据读取和下一个元素的左右子树的载入

void LevelOrder(BTNode* root)
{
	Queue q;//创建一个结构体,并且进行初始化
	QueueInit(&q);
	if (root)
		QueuePush(&q, root);//先第一个数据1
	while (!QueueEmpty(&q))//若不为空,一个一个元素的过,但是打印是按照顺序的
	{
		BTNode* front = QueueFront(&q);//选定第一个数据,拿出来放入指针中,然后进行删除
		//并且进行打印
		QueuePop(&q);

		printf("%d", front->data);//出来第一个根1 
		//左不为空,则带2出来
		//打印前提是将数据放入数组q中,这样可以带出该组数据的左右子树
		if (front->left)
			QueuePush(&q, front->left);
		//右不为空,带出4
		if (front->right)
			QueuePush(&q, front->right);
	 //下一轮就到了2,然后打印,再对2的左右进行遍历
	}
	printf("\n");
	QueueDestroy(&q); 
}

Tips

遍历的所有基本概念都围绕着根——左子树——右子树的顺序,存放在队列(数列)里也会是按照根——左子树——右子树顺序存放,我们接下来二叉树链式结构的实现,都会用到这样的递归思想

节点个数

由左右子树决定该节点承载的节点数

int BTreeSize(BTNode* root)
{
    if(root==NULL)
        return 0;
    return BTreeSize(root->left)+BTreeSize(root->right)+1;
}

解释如下:

二叉树叶子节点个数

思维同求全部节点的个数——由下方结点统计数量后再将数据归到最上层

叶子结点——度为0的结点,那么仅需要判断其左右子树为NULL即可

int BTreeLeafSize(BTNode* root)
{
    if(root==NULL)
        return 0;
    if(root->left==NULL&&root->right==NULL)
    {
        return 1;
    }
    return BTreeLeafSize(root->left)+BTreeLeafSize(root->right);

}

 第K层节点个数

重点在于如何在层序遍历的前提下,读取到第k层的数据

仍使用递归的思想,下层数据传递到上层

int BTreeLeafKSize(BTNode* root,int k)
{
    if(root==NULL)
    {
        return 0;
    }
    if(k==1)
    {
        return 1;
    }
    return BTreeLeafKSize(root->left,k-1)+BTreeLeafKSize(root->right,k-1);
}

查找值为x的节点

BTNode* BTreeFind(BTNode* root, BTDataType x)
{
    if(root==NULL)
        return NULL
    if(root->data==x)
        return root;
    BTNode* ret1=BTreeFind(root->left,x);
    if(ret1->data==x)
            return ret1;
    BTNode* ret2=BTreeFind(root->right,x);
    if(ret2->data==x)
            return ret2;
    return NULL:
}

同理,此处并不是从左右子树共同出发,而是先遍历完左树后再去遍历右树

然后用一个变量去保存,如果直接检验的话会造成数据的丢失

二叉树的高度

int BTreeHeight(BTNode* root)
{
    if(root==NULL)
        return 0;
    int LeftHeight=BTreeHeight(root->left);
    int RightHeight=BtreeHeight(root->right);
    return LeftHeight>RightHeight?LeftHeight+1:RightHeight+1;
}

本质其实就是统计出最后每一个分支的最大的节点数,便是二叉树的高度。

读到NULL就会返回0,说明此结点往后没有任何结点,然后便是要加上1,就是节点本身要计数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nick-An

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值