二叉树的链式结构实现

前言

对于一般的二叉树(非完全二叉树,满二叉树)而言。用顺序表去存储,会造成空间的浪费。所以一般采用链式结构实现。
对于非完全非满二叉树,增删查改并没有什么实际意义,对于以后学到的搜索二叉树会有。但是一般的操作是 前序、中序、后序 遍历二叉树,也可以写计算二叉树的深度,结点数,叶子结点数的功能函数。

链式结构实现

创建结点结构体

typedef struct BinaryTreeNode
{
	struct BinaryTreeNode* right;
	struct BinaryTreeNode* left;
	int data;
}BTNode;

构建树逻辑结构

在这里插入图片描述

BTNode* CreatTree()
{
	BTNode* n1 = (BTNode*)malloc(sizeof(BTNode));
	BTNode* n2 = (BTNode*)malloc(sizeof(BTNode));
	BTNode* n3 = (BTNode*)malloc(sizeof(BTNode));
	BTNode* n4 = (BTNode*)malloc(sizeof(BTNode));
	BTNode* n5 = (BTNode*)malloc(sizeof(BTNode));
	BTNode* n6 = (BTNode*)malloc(sizeof(BTNode));

	n1->data = 1;
	n2->data = 2;
	n3->data = 3;
	n4->data = 4;
	n5->data = 5;
	n6->data = 6;

	n1->left = n2;
	n1->right = n4;
	n2->left = n3;
	n2->right = NULL;
	n3->left = NULL;
	n3->right = NULL;
	n4->left = n5;
	n4->right = n6;
	n5->left = NULL;
	n5->right = NULL;
	n6->left = NULL;
	n6->right = NULL;

	return n1;
}

遍历二叉树

前序遍历:先访问根节点,再遍历其左子树、右子树。
中序遍历:先访问左子树,再访问根节点、其右子树。
后续遍历:先访问右子树,再访问根节点、其左子树。

运用递归的思想
前序遍历

void PreTravel(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
		printf("%d ", root->data);
	PreTravel(root->left);
	PreTravel(root->right);
}

中序遍历

void InTravel(BTNode* root)
{
	if (root== NULL)
	{
		printf("NULL ");
		return;
	}
	InTravel(root->left);
	printf("%d ", root->data);
	InTravel(root->right);
}

后序遍历

void PostTravel(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	PostTravel(root->left);
	PostTravel(root->right);
	printf("%d ", root->data);
}

计算二叉树高度、结点数、叶子数

结点数:

int TreeNodeSize(BTNode* root)
{
	return root == NULL ? 0 :
		TreeNodeSize(root->left) + TreeNodeSize(root->right) + 1;
}

在这里插入图片描述

叶子数:

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

在这里插入图片描述

高度:

int TreeHeightSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	int leftsize= TreeHeightSize(root->left);
	int rightsize = TreeHeightSize(root->right);

	return rightsize > leftsize ? rightsize + 1:leftsize + 1;
}

在这里插入图片描述
销毁

void Destory(BTNode* root)
{
	if (root == NULL)
		return;
	Destory(root->left);
	Destory(root->right);
	free(root);
}

查找值为x的节点

BTNode* TreeFind(BTNode* root, BTTypde x)
{
	if (root == NULL)
		return NULL;
	if (root->data==x)
		return root;
	BTNode*left= TreeFind(root->left, x);
	if (left)
		return left;
	BTNode*right=TreeFind(root->right, x);
	if (left)
		return right;
	
		return NULL;
}

层序遍历
利用队列。
先入根,再出队列,同时把左右子孩子入队列,依次如下,直到队列为空。
在这里插入图片描述

void BinaryTreeLevelOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root)
	{
		QueuePush(&q, root);
	}
	while (!EmptyQueue(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		printf("%d ", front->_data);
		if(front->_left)
			QueuePush(&q, root->_left);
		if(front->_right)
		QueuePush(&q, root->_right);

	}
	QueueDestory(&q);
}

判断是否为完全二叉树
也是利用队列,出队就入左右孩子,一旦出队列的是空,就停止,下面判断,如果后面全是空就是完全二叉树,但凡有一个非空就不是完全二叉树。

int BinaryTreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root)
	{
		QueuePush(&q, root);
	}
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front == NULL)
			break;
			QueuePush(&q, root->_left);
			QueuePush(&q, root->_right);
	}
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front != NULL)
		{
			QueueDestory(&q);
			return false;
		}
	}
	QueueDestory(&q);
	return true;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值