二叉树的表示方法
通常的⽅法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别⽤来给出该结点左孩⼦和右孩⼦所在的链结点的存储地址。
结构如下:
typedef int BTDataType;
// ⼆叉链
typedef struct BinaryTreeNode
{
struct BinTreeNode* left; // 指向当前结点左孩⼦
struct BinTreeNode* right; // 指向当前结点右孩⼦
BTDataType val; // 当前结点值域
}BTNode;
实现链式二叉树的方法
二叉树主要分为,空树和非空树,非空树主要是由节点,根节点左子树,根节点右子树组成的,实现链式二叉树可以运用递归进行代码的编写。二叉树的遍历方式分为,先序遍历(根节点,左子树,右子树),中序遍历(左子树,根节点,右子树),后续遍历(左子树,右子树,根节点)这三种遍历的方式。
遍历方式的练习:
1.设⼀棵 ⼆叉树的中序遍历序列:badce,后序遍历序列:bdeca,则⼆叉树前序遍历序列为____
2.某⼆叉树的后序遍历序列与中序遍历序列相同,均为 ABCDEF ,则按层次输出(同⼀层从左到右) 的序列为___。
二叉树的递归调用
二叉树的链式访问,运用的是递归,在这里我们可以体会到递归的美学,下面我们通过示意图进行具体的解释。
前序遍历,中序遍历,后续遍历基本思想都是运用了这张图所展现的思想就说递归,所以不足具体的解析了。
二叉树求k层节点的个数求解分析:求k层节点的个数这里面其实我开始也是不知道如何表示取到k层的,这里运用了图像进行了讲解。
二叉树深度求解分析:
⼆叉树查找值为x的结点分析:
层序遍历:
二叉树的销毁:
源代码
tree.h
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct BinaryTree
{
int data;
struct BinaryTree *left;
struct BinaryTree* right;
}tree;
//树的先序遍历
void PreOrder(tree* root);
//中序遍历
void InOrder(tree* root);
//后序遍历
void PostOrder(tree* root);
//树的销毁
void TreeDestory(tree* root);
//计算树的总节点个数
int TreeSize(tree* root);
//计算树叶子节点的个数
int TreeLeafSize(tree * root);
// ⼆叉树第k层结点个数
int TreeLevelKSize(tree* root, int k);
//⼆叉树的深度/⾼度
int TreeDepth(tree* root);
// ⼆叉树查找值为x的结点
tree* TreeFind(tree* root, int x);
// ⼆叉树销毁
void TreeDestory(tree** root);
//层序遍历
void LevelOrder(tree* root);
//判断二叉树是否为完全二叉树
bool TreeComplete(tree* root);
tree.c
#include"tree.h"
// 树的先序遍历
void PreOrder(tree* root)
{
if (root == NULL)
{
return;
}
printf("%d", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
// 树的中序遍历
void InOrder(tree* root)
{
if (root == NULL)
{
return;
}
InOrder(root->left);
printf("%d", root->data);
InOrder(root->right);
}
// 树的后序遍历
void PostOrder(tree* root)
{
if (root == NULL)
{
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%d", root->data);
}
//计算树的总节点个数
int TreeSize(tree* root)
{
if (root == NULL)
{
return 0;
}
return 1 + TreeSize(root->left) + TreeSize(root->right);
}
//计算树叶子节点的个数
int TreeLeafSize(tree* root)
{
if (root == NULL)
{
return 0;
}
//当某一个节点是下一个的左右两侧都为NULL时就可证明此时就是叶子节点
if (root->left == NULL && root->right == NULL)
{
return 1;
}
return TreeLeafSize(root->left)+ TreeLeafSize(root->right);
}
// ⼆叉树第k层结点个数
int TreeLevelKSize(tree* root, int k)
{
if (root == NULL)
{
return 0;
}
if (k == 1)
{
return 1;
}
return TreeLevelKSize(root->left, k - 1) + TreeLevelKSize(root->right, k - 1);
}
//⼆叉树的深度/⾼度
int TreeDepth(tree* root)
{
if (root == NULL)
{
return 0;
}
int LeftDepth = TreeDepth(root->left);
int RightDepth = TreeDepth(root->right);
return LeftDepth > RightDepth ? LeftDepth + 1 : RightDepth + 1;
}
// ⼆叉树查找值为x的结点
tree* TreeFind(tree* root, int x)
{
if (root == NULL)
{
return NULL;
}
if (root->data == x)
{
return root;
}
tree* leftFind = TreeFind(root->left, x);
if (leftFind)
{
return leftFind;
}
tree* rightFind = TreeFind(root->right, x);
if (rightFind)
{
return rightFind;
}
return NULL;
}
// ⼆叉树销毁
void TreeDestory(tree** root)
{
if (*root == NULL)
{
return;
}
//注意这里的传参
TreeDestory(&((*root)->left));
TreeDestory(&((*root)->right));
free(*root);
*root = NULL;
}
//层序遍历
void LevelOrder(tree* root)
{
Qu q;
QueueInit(&q);
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
//取队头,打印
tree* front = QueueFront(&q);
printf("%d ", front->data);
QueuePop(&q);
//队头节点的左右孩子入队列
if (front->left)
QueuePush(&q, front->left);
if (front->right)
QueuePush(&q, front->right);
}
//队列为空
QueueDestroy(&q);
}
//判断二叉树是否为完全二叉树
bool TreeComplete(tree* root)
{
}
test.c
#include"tree.h"
tree* buyNode(int x)
{
tree* newnode = (tree*)malloc(sizeof(tree));
if (newnode == NULL)
{
perror("malloc fail!");
exit(1);
}
newnode->data = x;
newnode->left = newnode->right = NULL;
return newnode;
}
void test01()
{
tree* node1 = buyNode(1);
tree* node2 = buyNode(2);
tree* node3 = buyNode(3);
tree* node4 = buyNode(4);
node1->left = node2;
node1->right = node3;
node2->right = node4;
PreOrder(node1);
printf("\n");
InOrder(node1);
printf("\n");
PostOrder(node1);
printf("\n");
printf("size:%d\n", TreeSize(node1));
printf("leaf size: %d\n", TreeLeafSize(node1));
printf("第K层size : %d\n", TreeLevelKSize(node1, 3));
printf("depth/height:%d\n", TreeDepth(node1));
tree* find =TreeFind(node1, 6);
printf("%s\n", find == NULL ? "未找到!" : "找到了!");
TreeDestory(&node1);
}
int main()
{
test01();
return 0;
}
总结
链式二叉树在计算机科学中有广泛的应用,例如在搜索算法、排序算法、表达式求值、图算法等领域。链式二叉树使用递归是非常方便的,但是我们不要忘记递归一定要有限制条件,不然递归就说无限制循环了。最后创作不易希望各位大佬可以留下珍贵的一键三连(点赞,收藏,关注)。