数据结构手撕--【二叉树】

目录

定义结构体:

初始化:

手动创建一个二叉树:

前序遍历:

中序遍历:

后序遍历

二叉树节点个数:

叶子节点个数:

二叉树第k层节点个数:

二叉树的高度:

查找值为x的节点:

二叉树的层序遍历:

判断二叉树是否为完全二叉树:

销毁二叉树:


二叉树增删查改没有具体意义。我们主要实现搜索二叉树

特殊的二叉树---完全二叉树(堆) 适合数组结构表示 (堆结构下节更新)

对于普通二叉树我们采用 链式结构

定义结构体:

一个结构体就是一个树节点

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//链式二叉树

//定义结构体 --- 一个结构体就是一个树节点
typedef char BTDataType;
typedef struct BinaryTreeNode
{
	BinaryTreeNode* left;  //指向节点的指针 类型为节点类型
	BinaryTreeNode* right;
	BTDataType data;
}BTNode;

初始化:

链式结构 开辟空间创建新节点

cpp 复制代码
BTNode BuyNode(BTDataType x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	newnode->left = NULL;
	newnode->right = NULL;
	newnode->data = x;
	return newnode;
}

手动创建一个二叉树:

cpp 复制代码
BTNode* CreatBinaryTree()
{
	BTNode* nodeA = BuyNode('A');
	BTNode* nodeB = BuyNode('B');
	BTNode* nodeC = BuyNode('C');
	BTNode* nodeD = BuyNode('D');
	BTNode* nodeE = BuyNode('E');
	BTNode* nodeF = BuyNode('F');

	nodeA->left = nodeB;
	nodeA->right = nodeC;
	nodeB->left = nodeD;
	nodeC->left = nodeE;
	nodeC->right = nodeF;
	return nodeA;
}

前序遍历:

--- 根左右 打印放在最前面 再左、右递归

cpp 复制代码
void PerOrder(BTNode* root)
{
	if (root == NULL)
	{
		return NULL;
	}
	printf("%c", root->data);
	PerOrder(root->left);
	PerOrder(root->right);
}

画图理解递归过程:

中序遍历:

--- 左根右 打印放在中间 先左递归 打印 再右递归

cpp 复制代码
void MidOrder(BTNode* root)
{
	if (root == NULL)
	{
		return NULL;
	}
	MidOrder(root->left);
	printf("%c", root->data);
	MidOrder(root->right);
}

后序遍历

-- 左右根

cpp 复制代码
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		return NULL;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%c", root->data);
}

二叉树节点个数:

为空返回0,不为空去递归左右子树,+1是递归完左右返回之后+1的,即就会算此时的root节点的数量。(下图有具体的递归过程)左+右+根(1)

cpp 复制代码
int BinaryTreeSize(BTNode* root)
{
	return root == NULLL ? 0 : BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

叶子节点个数:

走到叶子返回1(不再向下递归),返回 左+右 不算根的个数

cpp 复制代码
int BinaryTreeLeafSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	if (root->left && root->right == NULL) //在递归的过程中 走到叶子就会返回1 最后左+右即可
	{
		return 1;
	}
	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

二叉树第k层节点个数:

往下走一层k都会减一,假如要求第五层,走到第五层k=1,把1返回即可

cpp 复制代码
int BinaryTreeLeaveSize(BTNode* root, int k)
{
	if (root == NULL)
	{
		return 0;
	}
	if (k == 1)
	{
		return 1;
	}
	return BinaryTreeLeaveSize(root->left, k - 1) + BinaryTreeLeaveSize(root->right, k - 1);
}

二叉树的高度:

当这棵树为空树时,二叉树的高度应该是0,所以当数为空我们返回0,然而当树不等于空时,我们可以以大事化小,小事化了的思想,将当前树的高度转换成左右子树两个中的最大高度再加上一,然后左右子树中最大高度的树的高度又可以转换成我们刚刚的思想,就这样不断递归下去直接我们遇见空节点.

cpp 复制代码
nt BinaryTreeDepth(BTNode* root)
{
	//为空 返回0
	//递归左树 遇到左右都为空的节点 返回1 再递归右树 左右都为空 返回1,
	//左右比较 返回大的+1
	if (root == NULL)
	{
		return NULL;
	}
	NTNode* left = BinaryTreeDepth(root->left);
	NTNode* right = BinaryTreeDepth(root->right);
	return left > right ? left + 1 : right + 1;
}

查找值为x的节点:

只要找到了就不会返回空,只要返回的不是空就是找到了。左子树找到了就不会再去右子树找

cpp 复制代码
BTNode* BinaryTreeFind(BTNode* root, BTNodeType x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->data == x)
	{
		return root;
	}
	BTNode* left = BinaryTreeFind(root->left);
	if (left != NULL)
	{
		return left;
	}
	BTNode* right = BinaryTreeFind(root->right);
	if (left != NULL)
	{
		return right;
	}
	return NULL;
}

二叉树的层序遍历

借助队列

  1. 先将根入队列
  2. 当前节点出队列后,将次此节点的左右孩子入队列
  3. 一直这样循环往复直到队列为空,说明最后一层已经没有节点了,遍历结束
cpp 复制代码
void BinaryTreeLevelOrder(BTNode* root)
{
	if (root == NULL)
	{
		return NULL;
	}
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		printf("%c", front->data);
		if (front->left != NULL)
		{
			QueuePush(&q, front->left);
		}
		if (front->right != NULL)
		{
			QueuePush(&q, front->right);
		}
	}
	printf("\n");
	QueueDestroy(&q);
}

判断二叉树是否为完全二叉树:

完全二叉树和非完全二叉树的区别:前者一旦有空后面就都是空,而后者一旦有空后面还会出现非空。

第二个while循环是遇到空时候,看后面是否全为空,如果是就是完全二叉树

QueueEmpty(&q)判断队列是否为空,看的是front是否为空

cpp 复制代码
bool BinaryTreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front == NULL)
		{
			break;
		}
		else
		{
			QueuePush(&q, front->left);
			QueuePush(&q, front->right);
		}
	}
	//遇到空了
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front)
		{
			QueueDestory(&q);
			return false;
		}
	}
	QueueDestory(&q);
	return true;
}

销毁二叉树:

cpp 复制代码
void BinaryTreeDestory(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	BinaryTreeDestory(root->left);
	BinaryTreeDestory(root->right);
	free(root);
}
相关推荐
adam_life21 分钟前
http://noi.openjudge.cn/——2.5基本算法之搜索——200:Solitaire
算法·宽搜·布局唯一码
我想进大厂1 小时前
图论---朴素Prim(稠密图)
数据结构·c++·算法·图论
我想进大厂1 小时前
图论---Bellman-Ford算法
数据结构·c++·算法·图论
AIGC大时代1 小时前
高效使用DeepSeek对“情境+ 对象 +问题“型课题进行开题!
数据库·人工智能·算法·aigc·智能写作·deepseek
lkbhua莱克瓦241 小时前
用C语言实现——一个中缀表达式的计算器。支持用户输入和动画演示过程。
c语言·开发语言·数据结构·链表·学习方法·交友·计算器
CODE_RabbitV2 小时前
【深度强化学习 DRL 快速实践】近端策略优化 (PPO)
算法
Wendy_robot3 小时前
【滑动窗口+哈希表/数组记录】Leetcode 438. 找到字符串中所有字母异位词
c++·算法·leetcode
程序员-King.3 小时前
day49—双指针+贪心—验证回文串(LeetCode-680)
算法·leetcode·贪心算法·双指针
转基因3 小时前
Codeforces Round 1020 (Div. 3)(题解ABCDEF)
数据结构·c++·算法
Forworder4 小时前
[数据结构]树和二叉树
java·数据结构·intellij-idea·idea