1.定义
二叉树的每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且二叉树的子树有左右之分,其次序不能颠倒. 二叉树以递归的形式定义,二叉树是n(n>=0)个结点的有限集合:
- 或者为空二叉树,即n=0,
- 或者由一个根节点和两个互不相交的被称为根的左子树和右子树组成,左子树和右子树分别是一棵二叉树.
二叉树和度为2的有序树的区别:
(1)度为2的树至少有3个结点,而二叉树可以为空
(2)度为2的有序树的孩子节点的左右次序是相对于另一孩子结点而言的,如果某个结点只有一个孩子结点,这个孩子结点就无须区分其左右次序,而二叉树无论其孩子树是否为2,均需要确定其左右次序,也就是说二叉树的结点不是相对于另一个结点而言的,而是确定的.
2.几个特殊的二叉树
(1) 满二叉树:每一层结点都达到了当层能达到的最大结点数,满二叉树的叶子结点都在最下一层,除叶子结点外,每个结点的度数均为 2.
(2) 完全二叉树:除最下面的一层外,其余层的结点个数都达到了当层能达到的最大结点数:每个结点都与高度为h的满二叉树中编号为1~n的结点一一对应时,称之为完全二叉树.
(3) 排序二叉树: 一棵二叉树或者是空二叉树,或者是具有如下性质的二叉树:
左子树上所有结点的关键字均小于根结点的关键字,右子树上所有结点的关键字都大于根结点的关键字.左子树和右子树又各是一棵排序树.
(4)平衡二叉树: 树上任意结点的左子树和右子树的深度之差不超过1.
3.二叉树的存储结构
二叉树的顺序存储结构就是用一组地址连续的存储单元依次从上而下、自左向右存储完全二叉树的结点元素,即将完全二叉树上编号为i的结点元素存储在某个数组下标为i-1的分量中,完全二叉树和满二叉树采用顺序存储比较合适,树种结点的序号可以唯一地反映出结点之间的逻辑 关系,这样既能最大可能节省存储空间,又可以利用数组元素的下标确定结点在二叉树中的位置,以及结点之间的关系。
4.二叉树的链式存储
由于顺序存储对空间的利用率较低,因此,一般二叉树都采用链式存储结构。链式结构是指用一个链表来存储一棵二叉树,二叉树中每一个结点用链表的一个链结点来存储。二叉链表至少包含三个域,数据域data、左指针域lchild、右指针域rchild。
5.二叉树的基本操作
链表结点的描述如下:
struct node{
int data; //数据域
node* lchild; //左指针域
node* rchild; //右指针域
};
由于在二叉树建树前根节点不存在,因此其地址一般设为NULL;
node* root = NULL;
新建结点函数代码如下:
//生成一个新节点
node* newNode(int v){
node* Node = new node; //申请一个node型变量的地址空间
Node->data = v; //结点权值为v
Node->lchild = Node->rchild = NULL; //初始状态没有左右孩子
return Node; //返回新建结点的地址
}
二叉树的查找操作是指在给定的条件下,在二叉树中找到所有数据域为给定数据域的结点,并将它们的数据域修改为给定的数据域。代码如下:
void search(node* root, int x, int newdata){
if(root == NULL) return; //空树 ,递归结束
//找到数据域为x的结点,把它修改成nexdata
if(root->data == x) return root->data = newdata;
search(root->lchild; x, newdata); //左子树搜索
search(root->rchild; x, neadata); //右子树搜索
}
二叉树结点的插入位置一般取决于数据域需要在二叉树中存放的位置,且对于给定的结点来说,它在二叉树中的插入位置只会有一个,即二叉树结点的插入位置就是数据域在二叉树中查找失败的位置。代码如下:
//insert函数将在二叉树中插入一个数据域为x的新节点
//注意根节点指针root要使用引用,否则插入不会成功
void insert(node* &root, int x){
if(root == NULL){ //空树,说明查找失败,
root = newNode(x);
return;
}
if(由二叉树的性质,x应该插在){ //if(root->data > x)
insert(root->lchild, x); //左子树递归
}
else{
insert(root->rchild, x); //右子树递归
}
}
二叉树的创建其实就是二叉树结点的插入过程,而插入过程所需要的结点数据域一般都会由题目给出,代码如下:
//二叉树的建立
node* Create(int data[], int n){
node* root = NULL; //新建空根节点root
for(int i=0; i<n; i++){
insert(root, data[i]); //将data[0]~data[i-1]插入二叉树中
}
return root; //返回根节点
}