首先我们得清楚什么是树?什么样的树又是二叉树?
1.树:由N(N>=0)个结点构成的集合。对N>1的树,有:
1.有一个特殊的结点,称为根结点,根节点没有前驱结点,除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集合Ti(1<= i <= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继。因此,树是递归定义的。树的结构大致如下图所示:
2.与树相关的概念:
(1) 结点:结点包括一个数据元素及若干指向其他子树的分支(指针(索引))
(2) 结点的度:结点所拥有子树的个数称为该结点的度
(3) 叶结点:度为0的结点称为叶结点,叶节点也称为终端节点
(4) 分支结点:度不为0的结点称为分支结点,分支结点也称为非终端节点。一棵树中除叶节点外的所有节点都是分支结点
(6) 祖先结点:从根节点到该结点所经分支上的所有节点
(7) 子孙结点:以某节点为根节点的子树中所有节点
(8) 双亲结点:树中某节点有孩子结点,则这个结点称为它孩子结点的双亲结点,双亲结点也称为前驱结点
(9) 孩子结点:树中一个节点的子树的根节点称为该结点的孩子结点,孩子结点也称为后继结点
(10)兄弟结点:具有相同双亲结点的结点称为兄弟结点
(11)树的度:树中所有节点的度的最大值称为该树的度
(12)结点的层次:从根节点到树中某节点所经路径上的分支数称为该结点的层次,根节点的层次为1,其他结点层次是其双亲结点层次加1
(13)树的深度:树中所有节点的层次的最大值称为该树的深度
(14)有序树:树中结点的各棵子树T0、T1…是有序的,即为有序树。其中T1叫做根的第一棵子树,T2叫着根的第二棵子树
(15)无序树:树中结点的各棵子树之间的次序不重要,可以相互交换位置
3.二叉树及其相关概念
(1)一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵分别称为左子树和右子树的二叉树组成
(2)二叉树的特点:每个结点最多有两棵子树,即二叉树不存在度大于2的结点二叉树的子树有左右之分,其子树的次序不能颠倒
测试环境:vs2013
(3)满二叉树:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子节点都在同一层上
(4)完全二叉树:如果一棵具有N个结点的二叉树的结构与满二叉树的前N个结点的结构相同,称为完全二叉树
(5)二叉树的性质:
<1>若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1)(i>0)个结点
<2>若规定只有根节点的二叉树的深度为1,则深度为K的二叉树的最大结点数是2^k - 1 (k>=0)
<3>对任何一棵二叉树, 如果其叶结点个数为 n0, 度为2的非叶结点个数为 n2,则有n0=n2+1
<4>具有n个结点的完全二叉树的深度k为 log2^(n-+)上取整
BinTree.c
#include "BInTree.h"
// 构建二叉树的结点
PBTNode BuyBinTreeNode(BTDataType data)
{
PBTNode PNewNode = NULL;
PNewNode = (PBTNode)malloc(sizeof(BTNode));
if (PNewNode == NULL)
{
printf("空间申请失败!!!\n");
return NULL;
}
PNewNode->_data = data;
PNewNode->_pLeft = NULL;
PNewNode->_pRight = NULL;
return PNewNode;
}
//正真用来创建二叉树
//这里的思路就是将二叉树的每个节点当作一颗新树,创建新树的跟节点,
//然后创建跟节点的左子树,最后创建右子树,这样就将问题规模缩小,可以递归起来
void _CreateBinTree(PBTNode* pRoot, const BTDataType* arr, int size, int* index, BTDataType invalid)
{
assert(pRoot);
//如果arr[*index]不等于'#',且索引index没有越界,那就创建跟节点
if (arr[*index] != invalid && *index < size)
{
//创建跟节点
*pRoot = BuyBinTreeNode(arr[*index]);
//创建左子树
//注意:这里的(*index++)是在你要创建的时候去++,而不是再创建之后
(*index)++;
_CreateBinTree(&((*pRoot)->_pLeft), arr, size, index, invalid);
//创建右子树
(*index)++;
_CreateBinTree(&((*pRoot)->_pRight), arr, size, index, invalid);
}
}
//给用户的接口
void CreateBinTree(PBTNode* pRoot, const BTDataType* arr, int size, BTDataType invalid)
{
int index = 0;//用来索引传过来的字符串
assert(pRoot);
if (arr == NULL)
return;
_CreateBinTree(pRoot, arr, size, &index, invalid);//因为要在另一个函数内部改变index的值,所以传地址
}
//前序遍历二叉树:根-->左子树-->右子树
//递归
void PreOrder(PBTNode pRoot)
{
//如果根节点不为空,遍历
if (pRoot)
{
printf("%c ", pRoot->_data);
//如果左子树不为空,遍历
//判断是为了减少递归次数
if (pRoot->_pLeft)
PreOrder(pRoot->_pLeft);
//如果右子树存在,遍历
if (pRoot->_pRight)
PreOrder(pRoot->_pRight);
}
}
//初始化栈
void StackInit(PStack s)
{
assert(s);
s->size = 0;
}
//入栈
void StackPush(PStack s, SDataType data)
{
assert(s);
if (s->size == MAX_SIZE)
{
printf("栈已满!\n");
return;
}
s->arr[s->size] = data;
s->size++;
}
//出栈
void StackPop(PStack s)
{
assert(s);
i