核心概念
树结构,类似于"文件夹系统"或公司的"组织架构图"它是一对多的非线性结构
根节点:整棵树最顶层的唯一节点(没有父节点)
父节点与子节点:A 是 B 的直接上级,A 就是父,B 就是子。
叶子节点:没有子节点的末端节点(就像公司里没有下级的一线员工)。
度:一个节点拥有的子树个数(比如一个领导直接管几个部门)。
深度/高度:从根到该节点经过的边数(层级深度)。
二叉树遍历方式
前序遍历(根-左-右):常用于复制整棵树或输出目录结构。
中序遍历(左-根-右):对二叉搜索树使用,结果是有序数组(这是面试高频点)。
后序遍历(左-右-根):常用于计算文件夹总大小(先算子文件夹,再汇总给父级)或删除树。
层序遍历(广度优先 BFS):一层一层扫,常用于寻找最短路径或判断树是否是"完全二叉树"。
可以通过#表示此根没有子树,用前序序列来通过一串字符表示一颗二分树
char tree_seq\[\] = "ABDG##H###CE#I##F##";
如此,通过递归函数可以快速创建一颗想要的树
#include <stdio.h>
#include <stdlib.h>
#include "linkqueue.h"
#include "btree.h"
typedef int data_t;
typedef struct btnode
{
data_t data;
struct btnode *pl;
struct btnode *pr;
}btree_t; //二叉树节点类型
char tree_seq[] = "ABDG##H###CE#I##F##";
//char tree_seq[] = "AB#CD##E##F#GH###";
int idx = 0;
btree_t *create_btree(void)
{
char data = tree_seq[idx++];
if (data == '#')
{
return NULL; //表示结束
}
btree_t *new = malloc(sizeof(btree_t));
if (new == NULL)
{
printf("malloc fail!\n");
return NULL;
}
new->data = data;
new->pl = create_btree();
new->pr = create_btree();
return new;
}
注意idx是全局变量,每次使用后需要移动
int pre_order_traverse(btree_t *t) //传根节点的地址
{
// 结束条件 t == NULL
if (t == NULL)
return 0;
printf("%c ",t->data); //根
pre_order_traverse(t->pl); //左子树 //左
pre_order_traverse(t->pr); //右子树 //右
return 0;
}
int in_order_traverse(btree_t *t) //传根节点的地址
{
// 结束条件 t == NULL
if (t == NULL)
return 0;
in_order_traverse(t->pl); //左子树 //左
printf("%c ",t->data); //根
in_order_traverse(t->pr); //右子树 //右
return 0;
}
int post_order_traverse(btree_t *t) //传根节点的地址
{
// 结束条件 t == NULL
if (t == NULL)
return 0;
post_order_traverse(t->pl); //左子树 //左
post_order_traverse(t->pr); //右子树 //右
printf("%c ",t->data); //根
return 0;
}
与创建时类似的,可以以前序中序后序三种方式遍历树
销毁树
int btree_destroy(btree_t *t) // 销毁二叉树
{
if (t == NULL)
return -1;
//递归 --- 后序方式
//左右根
btree_destroy(t->pl);//左
btree_destroy(t->pr);//右边
free(t);
return 0;
}
必须要以后序方式销毁,否则根丢失后无法销毁子树
通过队列来层序遍历树
int layer_order_traverse(btree_t *t)
{
if (t == NULL)
return -1;
//s1.创建队列
node_t *pq = linkqueue_create();
enqueue(pq,t);
while (is_empty(pq) != 1)
{
btree_t *data = NULL;
dequeue(pq,&data);
printf("%c ",data->data);
if (data->pl != NULL)
enqueue(pq,data->pl);
if (data->pr != NULL)
enqueue(pq,data->pr);
}
linkqueue_destroy(&pq);
return 0;
}