您的位置:首页 > 理论基础 > 数据结构算法

C语言基本数据结构之二(二叉树的三种遍历,节点数以及深度算法)

2016-12-05 19:29 661 查看
关于二叉树的定义,网上有比较好的介绍,在这里就简单介绍二叉树的一些性质

二叉树的基本性质

1)二叉树的第i层上至多有 2^(i-1)(i ≥1)个结点;

2)深度为 h 的二叉树中至多含有 2^h – 1 个结点;

3)若在任意一棵二叉树中,有 n0 个叶子结点,有 n2 个度为 2 的结点,则:n0 = n2 + 1。

特殊形式的二叉树

1)满二叉树

特点:深度为h且含有2h-1个结点的二叉树,为满二叉树。图示满二叉树,结点编号为自上而下,自左而右。

2)完全二叉树(左图)

特点:指深度为k的,有n个结点的,且每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应,完全一致,则为完全二叉树。(右图)





3)平衡二叉树

特点:又称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): 按后序遍历左子树,按后序遍历右子树,访问根结点。

还是直接上代码吧~~这里用的是链式存储结构,相对顺序存储结构,前者所需存储容量更小,更易于理解~~

二叉树的结构体
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;
}


先序,中序,后序遍历的递归算法(ps:递归真是个好东西~~,写出来的代码就是简洁~~)
/*
先序遍历
*/
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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐