一、二叉树的定义
通用树结构是采用双亲孩子表示法模型建立的,每个结点都有一个指向其双亲的指针;每个结点
都有若干个指向其孩子的指针。但是我们还有另一种树的模型,那就是孩子兄弟表示法模型,每个结
点都有一个指向其第一个孩子的指针,每个结点都有一个指向其第一个右兄弟的指针;每个结点包含
一个数据指针和两个结点指针:
数据指针:指向保存于树中的数据;
孩子结点指针:指向第一个孩子;
兄弟结点指针:指向第一个右兄弟。
这种模型表示法的特点是能够表示任意的树型结构,每个结点中有且仅有三个指针域(数据指针、孩
子结点指针、兄弟结点指针),每个结点的结构简单,只有孩子结点和兄弟结点指针构成了“树
杈”。
1>定义:二叉树是由
n(n>=0)个结点组成的有限集合,该集合或者为空,或者是由一个根结点加上
两
棵分别称为
左子树和
右子树的、互不相交的二叉树组成。
满二叉树(Full Binary Tree):如果二叉树中所有的分支结点的度数都为2,且叶子结点都在同
一层次上,则称这类二叉树为满二叉树。
完全二叉树(Complete Binary Tree):如果一棵具有n个结点的高度为k的二叉树,它的每一个结
点都与高度为k的满二叉树中编号为
1--n的结点一一对应,则称这棵二叉树为完全二叉树。(从上到
下,从左到右编号)。
完全二叉树的叶结点出现在最下面两层,最下层的叶节点一定出现在左边,倒数第二层的叶结点一定
出现在右边;完全二叉树中度为1的结点只有左孩子;同样结点数的二叉树,完全二叉树的高度最
小。
二、二叉树的深层性质
1>性质1:在二叉树的第i层最多有2的i-1次方幂个结点。(i > 1).
2>性质2:深度为k的二叉树最多有2的k次方幂-1个结点。(k>0);
3>性质3:对任何一棵二叉树,如果其叶结点有n0个,度为2的非叶结点有n2个,则有n0=n2+1.
4>性质4:具有n个结点的完全二叉树的高度为
[log2n]+1.
5>性质5:一棵具有n个结点的二叉树(高度为
[log2n]+1),按层次对结点进行编号,对任意的结点i有:
如果i=1,则结点i是二叉树的根;
如果i>1,则其双亲结点为[i/2];
如果2i<=n,则结点i的左子树为2i;
如果2i>n,则结点i无左子树;
如果2i+1<=n,则结点i的右孩子为2i+1;
如果2i+1>n,则结点i无右孩子。
三、创建二叉树
1>指路法定位结点:指路法通过结点与目标结点的相对位置进行定位,可以避开二叉树递归的性质“线性”定位。思想:在c语言中可以利用bit位进行指路
#define BT_LEFT 0
#define BT_RIGHT 1
typedef unsigned long long BTPos;
2>二叉树存储结构
用结构体来定义二叉树中的指针域,二叉树的头结点也可以用结构体实现;
结点指针域定义:
typedef struct _tag_BTreeNode BTreeNode;
struct _tag_BTreeNode
{
BTreeNode* left;
BTreeNode* right;
};
头结点定义:
typedef struct _tag_BTree TBTree;
struct _tag_BTree
{
int count;
BTreeNode* root;
};
数据元素定义示例:
struct Node
{
BTreeNode header;
char v;
};
3>二叉树的操作
关键技巧:利用二进制的0和1分别表示left和right,位元算是实现指路法的基础。
while( (count > 0 ) && (current != NULL ) )
{
bit = pos & 1;
pos = pos >> 1;
count--;
parent = current;
if( bit == BT_LEFT)
current = current->left;
else if( bit == BT_RIGHT )
current = current->right;
}