关于二叉树的定义,网上有比较好的介绍,在这里就简单介绍二叉树的一些性质
二叉树的基本性质
1)二叉树的第i层上至多有 2^(i-1)(i ≥1)个结点;
2)深度为 h 的二叉树中至多含有 2^h – 1 个结点;
3)若在任意一棵二叉树中,有 n0 个叶子结点,有 n2 个度为 2 的结点,则:n0 = n2 + 1。
2)深度为 h 的二叉树中至多含有 2^h – 1 个结点;
3)若在任意一棵二叉树中,有 n0 个叶子结点,有 n2 个度为 2 的结点,则:n0 = n2 + 1。
特殊形式的二叉树
1)满二叉树
特点:深度为h且含有2h-1个结点的二叉树,为满二叉树。图示满二叉树,结点编号为自上而下,自左而右。
2)完全二叉树(左图)
特点:指深度为k的,有n个结点的,且每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应,完全一致,则为完全二叉树。(右图)
特点:深度为h且含有2h-1个结点的二叉树,为满二叉树。图示满二叉树,结点编号为自上而下,自左而右。
2)完全二叉树(左图)
特点:指深度为k的,有n个结点的,且每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应,完全一致,则为完全二叉树。(右图)
3)平衡二叉树
特点:又称AVL树,它或为一棵空树,或具如下性质:其左子树和右子树都是平衡二叉树,且左、右子树的深度之差的绝对值不超过1。左、右子树的深度之差为平衡因子,平衡二叉树的平衡因子只能为0,-1,1。
特点:又称AVL树,它或为一棵空树,或具如下性质:其左子树和右子树都是平衡二叉树,且左、右子树的深度之差的绝对值不超过1。左、右子树的深度之差为平衡因子,平衡二叉树的平衡因子只能为0,-1,1。
关于二叉树的存储方式(顺序和链式存储)
(1) 顺序存储结构
用一组连续的存储单元存放二叉树的数据元素。结点在数组中的相对位置蕴含着结点之间的关系。
其所需的存储单元数为:2^h-1= 24-1 = 15,若父结点在数组中i下标处,其左孩子在2*i处,右孩子在2*i+1处。
(2)链式存储结构
链式存储结构的每个结点由数据域、左指针域和右指针域组成。左指针和右指针分别指向下一层的二叉树
放二叉树的数据元素。结点在数组中的相对位置蕴含着结点之间的关系
关于二叉树的三种遍历方式
(1)先序遍历(D L R): 访问根结点,按先序遍历左子树,按先序遍历右子树。
(2)中序遍历(L D R): 按中序遍历左子树,访问根结点,按中序遍历右子树。
(3)后序遍历(L R D): 按后序遍历左子树,按后序遍历右子树,访问根结点。
(2)中序遍历(L D R): 按中序遍历左子树,访问根结点,按中序遍历右子树。
(3)后序遍历(L R D): 按后序遍历左子树,按后序遍历右子树,访问根结点。
还是直接上代码吧~~这里用的是链式存储结构,相对顺序存储结构,前者所需存储容量更小,更易于理解~~
二叉树的结构体
struct Tree{
int data;//这里可以改成你想要的数据类型
tree *left;
tree *right;
};
tree *initTree(tree* H){
H = NULL;
int data = 0;
printf(" 输入data \n ");
scanf("%d",&data);
if(data!=0){
H = (tree *)malloc(sizeof(tree));
H->data = data;
printf(" t data is %d \n",H->data);
printf(" 请输入左字树data \n");
H->left = initTree(H->left);
printf(" 请输入右字树data \n");
H->right = initTree(H->right);
}
return H;
}
/*
先序遍历
*/
void DLR(tree* T){
if(NULL!=T){
printf(" data is %5d \n ",T->data);
DLR(T->left);
DLR(T->right);
}
}
/*
中序遍历
*/
void LDR(tree* T){
if(NULL!=T){
LDR(T->left);
printf(" data is %5d \n",T->data);
LDR(T->right);
}
}
/*
后序遍历
*/
void LRD(tree* T){
if(NULL!=T){
LRD(T->left);
LRD(T->right);
printf(" data is %5d \n",T->data);
}
}
二叉树的层次遍历
void LOrder(tree* T) /* 层次遍历二叉树T */
{ treeQ[MAXNODE]; /* 辅助队列,MAXNODE为最大的队列容量 */
int f,r; /* 队列的首、尾指针 */
if (T == NULL) return; /* 空树,直接返回 */
f = -1; /* 队首,队尾指针初始化 */
r = 0;
Q[r] = T; /* 树根进队 */
while( f != r )
{ f++;
printf(“%d”,Q[f]->data); /* 访问队首结点的数据域 */
if (Q[f]->left!= NULL) /* 将队首结点的左孩子入队列 */
{ r++;
Q[r] = Q[f]->left; }
if (Q[f]->right!= NULL) /* 将队首结点的右孩子入队列 */
{ r++;
Q[r] = Q[f]->right; }
}
}
/*计算树的深度*/
int deep(tree* H){
int d1 = 0;
int d2 = 0;
if(NULL!=H){
d1 = deep(H->left) +1;
d2 = deep(H->right) +1;
}
return d1>=d2? d1:d2;
}
//计算总的节点数
int node(tree* H){
int n = 0;
if(NULL!=H){
n = node(H->left)+node(H->right) +1;
}
return n;
}
//计算叶子节点
int CountLeaf(tree* H){
if(NULL==H) return 0;
if((NULL==H->left)&&(NULL==H->right)){
return 1;
}
return CountLeaf(H->left) + CountLeaf(H->right);
}
全部代码如下
#include <stdio.h>
#include <malloc.h>
typedef struct Tree tree ;
/*
定义二叉树的结构体
*/
struct Tree{
int data;
tree *left;
tree *right;
};
tree *p[100];
/*
初始化二叉树
*/
tree *initTree(tree* H){
H = NULL;
int data = 0;
printf(" 输入data \n ");
scanf("%d",&data);
if(data!=0){
H = (tree *)malloc(sizeof(tree));
H->data = data;
printf(" t data is %d \n",H->data);
printf(" 请输入左字树data \n");
H->left = initTree(H->left);
printf(" 请输入右字树data \n");
H->right = initTree(H->right);
}
return H;
}
/*
先序遍历
*/
void DLR(tree* H){
if(NULL!=H){
printf(" data is %5d \n ",H->data);
DLR(H->left);
DLR(H->right);
}
}
/*
中序遍历
*/
void LDR(tree* H){
if(NULL!=H){
LDR(H->left);
printf(" data is %5d \n",H->data);
LDR(H->right);
}
}
/*
后序遍历
*/
void LRD(tree* H){
if(NULL!=H){
LRD(H->left);
LRD(H->right);
printf(" data is %5d \n",H->data);
}
}
/*
计算树的深度
*/
int deep(tree* H){
int d1 = 0;
int d2 = 0;
if(NULL!=H){
d1 = deep(H->left) +1;
d2 = deep(H->right) +1;
}
return d1>=d2? d1:d2;
}
//计算总的节点数
int node(tree* H){
int n = 0;
if(NULL!=H){
n = node(H->left)+node(H->right) +1;
}
return n;
}
//计算叶子节点
int CountLeaf(tree* H){
if(NULL==H) return 0;
if((NULL==H->left)&&(NULL==H->right)){
return 1;
}
return CountLeaf(H->left) + CountLeaf(H->right);
}
void main(){
tree *H = (tree*)malloc(sizeof(tree)) ;
H = initTree(H);
printf("DLR : \n");
DLR(H);
printf("LDR : \n");
LDR(H);
printf("LRD : \n");
LRD(H);
printf("\n deep is %5d \n ",deep(H));
printf(" CountLeaf is %5d \n",CountLeaf(H));
printf(" node number is %5d \n",node(H));
}
3)平衡二叉树
特点:又称AVL树,它或为一棵空树,或具如下性质:其左子树和右子树都是平衡二叉树,且左、右子树的深度之差的绝对值不超过1。左、右子树的深度之差为平衡因子,平衡二叉树的平衡因子只能为3)平衡二叉树
特点:又称AVL树,它或为一棵空树,或具如下性质:其左子树和右子树都是平衡二叉树,且左、右子树的深度之差的绝对值不超过1。左、右子树的深度之差为平衡因子,平衡二叉树的平衡因子只能为0,-1,1。