一.二叉树(binary tree)
二叉树(binary tree)是一种非线性数据结构,代表“祖先”与“后代”之间的派生关系,体现了“一分为二”的分治逻辑。与链表类似,二叉树的基本单元是节点,每个节点包含值、左子节点引用和右子节点引用。
每个节点都有两个引用(指针),分别指向左子节点(left-child node)和右子节点(right-child node),该节点被称为这两个子节点的父节点(parent node)。当给定一个二叉树的节点时,我们将该节点的左子节点及其以下节点形成的树称为该节点的左子树(left subtree),同理可得右子树(right subtree)。
2.二叉树的常用术语
根节点(root node):位于二叉树顶层的节点,没有父节点。
叶节点(leaf node):没有子节点的节点,其两个指针均指向 None 。
边(edge):连接两个节点的线段,即节点引用(指针)。
节点所在的层(level):从顶至底递增,根节点所在层为 1 。
节点的度(degree):节点的子节点的数量。在二叉树中,度的取值范围是 0、1、2 。
二叉树的高度(height):从根节点到最远叶节点所经过的边的数量。
节点的深度(depth):从根节点到该节点所经过的边的数量。
节点的高度(height):从距离该节点最远的叶节点到该节点所经过的边的数量。
3.常见的二叉树类型
(1)完美二叉树(满二叉树)
(2)完全二叉树
4.二叉树遍历
(1)层序遍历(广度优先遍历)从顶部到底部逐层遍历二叉树,并在每一层按照从左到右的顺序访问节点。
二,二叉树代码
1.头文件
#ifndef __TREE_H__
#define __TREE_H__
typedef char TDataType;
typedef struct tnode
{
TDataType data;
struct tnode *pl;
struct tnode *pr;
}TNode_t;
extern TNode_t *create_bin_tree();
extern void pre_order(TNode_t *proot);
extern void mid_order(TNode_t *proot);
extern void pos_order(TNode_t *proot);
extern int get_tree_node_cnt(TNode_t *proot);
extern int get_tree_layer_cnt(TNode_t *proot);
extern void destroy_tree(TNode_t *proot);
#endif
2.创建二叉树
#include "tree.h"
#include <stdlib.h>
#include <stdio.h>
#include "queue.h"
char tree[] = {"ABEH###G##CF#D##I##"};
int idx = 0;
TNode_t *create_bin_tree()
{
TDataType data = tree[idx++];
if (data == '#')
{
return NULL;
}
TNode_t *pnode = malloc(sizeof(TNode_t));
if (NULL == pnode)
{
perror("fail malloc");
return NULL;
}
pnode->data = data;
pnode->pl = create_bin_tree();
pnode->pr = create_bin_tree();
return pnode;
}
3.前序遍历
void pre_order(TNode_t *proot)
{
if (NULL == proot)
{
return;
}
printf("%c", proot->data);
pre_order(proot->pl);
pre_order(proot->pr);
}
4.中序遍历
void mid_order(TNode_t *proot)
{
if (NULL == proot)
{
return ;
}
mid_order(proot->pl);
printf("%c", proot->data);
mid_order(proot->pr);
}
5.后序遍历
void pos_order(TNode_t *proot)
{
if (NULL == proot)
{
return ;
}
pos_order(proot->pl);
pos_order(proot->pr);
printf("%c", proot->data);
}
6.节点个数
int get_tree_node_cnt(TNode_t *proot)
{
if (NULL == proot)
{
return 0;
}
return get_tree_node_cnt(proot->pl)+get_tree_node_cnt(proot->pr)+1;
}
7.层度
int get_tree_layer_cnt(TNode_t *proot)
{
if (NULL == proot)
{
return 0;
}
int cntl = get_tree_layer_cnt(proot->pl);
int cntr = get_tree_layer_cnt(proot->pr);
return cntl > cntr ? cntl + 1 : cntr + 1;
}
8.销毁二叉树
void destroy_tree(TNode_t *proot)
{
if (NULL == proot)
{
return ;
}
destroy_tree(proot->pl);
destroy_tree(proot->pr);
free(proot);
}
9.层序遍历
void layer_order(TNode_t *proot)
{
QDataType outdata;
Queue_t *pque = create_queue();
if (NULL == pque)
{
printf("fail create_queue\n");
return ;
}
push_queue(pque, proot);
while (!is_empty_queue(pque))
{
pop_queue(pque, &outdata);
printf("%c", outdata->data);
if (outdata->pl != NULL)
{
push_queue(pque, outdata->pl);
}
if (outdata->pr != NULL)
{
push_queue(pque, outdata->pr);
}
}
destroy_queue(pque);
}