数据结构之二叉树C语言实现版
文章目录
什么是树?
树(Tree)是n个节点的有限集,它可以是空树(n=0),也可以是为空树。对于非空树有以下特征:
- 有且仅有一个称之为根的节点
- 除了根节点外的其他节点可分为m(m>0)个互不相交的有限集T1,T2,…,Tm,其中每个集合本身又是一棵树,并且称为根的子树。
树的基本术语
树的样子
以下定义来自名为《数据结构C语言版|第2版》严蔚敏等编著 的教科书。然后加了一些自己的理解。
-
节点:树中的一个独立单元。包含一个数据元素和若干个指向其子树的分支。
-
节点的度:节点拥有的子树称为节点的度。就是父亲下面有几个儿子。
-
树的度:树的度是树内各节点度的最大值。整个家族里儿子最多的节点的儿子有多少,树的度就为多少。
-
叶子:度为零的节点称为叶子。就是节点之后没有其他节点了,这样的节点就是叶子
-
非终端节点:度不为零的节点称为非终端节点。除根节点之外,非终端节点也称为内部节点。
-
双亲和孩子:节点的子树的根称为该节点的孩子(儿子,因为说女儿听起来就挺奇怪的),相应地,该节点称为孩子的双亲(父亲或母亲)
-
兄弟:同一个双亲的孩子之间互称为兄弟或姊妹。
-
祖先:从根节点到该节点所经历的所有节点。就是一个节点之前的所有节点都叫它的祖先。
-
子孙:以某节点为根节点的子树汇总的任一节点都称为该节点的子孙。
-
层次:节点的层次从根开始定义其,根为第一层,根的孩子为第二层。树中任一节点的层次等于其双亲节点的层次加1。
-
堂兄弟:双亲在同一层的节点互为堂兄弟。
-
树的深度:树中节点的最大层次称为树的深度或高度。从根到离它最远的那个节点的层次就是树的深度。
-
有序树和无序树:如果将树中节点的各子树看成从左到右是有次序的(即不能互换),则称该树为有序树,否则称为无序树。在有序树中最左边的子树的根称为第一个孩子,最右边的称为最后一个孩子。
-
森林:是m(m>=0)棵互不相干的树的集合,字面意思理解,很多树的集合。
二叉树的定义
二叉树的单元的样子
二叉树的性质
- 二叉树本身也是树
- 有且仅有一个根节点
- 除根节点外的其余节点分为两个互不相干的子集T1和T2,分别称为T的左子树和右子树,且T1和T2本身又都是二叉树。
- 树可以有任意棵子树,二叉树每个节点至多只有两棵子树。
- 二叉树的子树有左右之分,其次序不能任意颠倒。
二叉树的实现
理论知识直接看书就完事了,主要看的是二叉树的实现过程。
二叉树结构体形式
typedef struct Node
{
int data;
struct Node* leftChild;
struct Node* rightChild;
}Node,*pNode;
使用typedef起个别名毕竟C++用习惯了。
二叉树节点的创建
pNode creatNode(int data)
{
pNode newNode = (pNode)malloc(sizeof(Node));
assert(newNode); //断言
newNode->data = data;
newNode->leftChild = NULL;
newNode->rightChild = NULL;
return newNode;
}
这个创建方式和双向循环链表的创建方式是一样的,但是后续使用不一样。
插入节点
void insertNode(pNode fatherNode, pNode leftChild, pNode rightChild)
{
fatherNode->leftChild = leftChild;
fatherNode->rightChild = rightChild;
}
这种插入方式的显得很呆,但是比较好理解。直接就是那二叉树的单元一个个练起来。
递归遍历二叉树
二叉树和其他的数据结构有点不同,一般使用二叉树的时候基本只是存储,所以知道怎么存储和怎么遍历的就可以了。
二叉树的遍历格式有三种,分别是:
- 前序:三个三个的看,先打印根节点然后打印左子树节点最后打印右子树节点,简称根左右
- 中序:三个三个的看,先打印左子树节点然后打印根节点最后打印右子树节点,简称左根右
- 后序:三个三个的看,先打印左子树节点然后打印右子树节点最后打印根节点,简称左右根
通过案例来理解一下:
现在有一个二叉树:
手动的书写打印结果:三个三个看
前序:
一、123
二、12453
三、124753
四、12475368
最终结果:12475368
中序:
一、213
二、42513
三、472513
四、47251386
最终结果:47251386
后序:
一、231
二、45231
三、