定义:
二叉树是一种每个结点至多有两棵子树(即每个结点的度最大为 2 )的有序树。
若一个节点有子树,那么该节点称为子树根节点的“双亲“,子树的跟是该节点的“孩子”。有相同双亲的节点互为“兄弟节点”。一个节点的所有子树上的任何节点都是该节点的后裔。从根节点到某个节点的路径上的所有节点都是该节点的祖先。
节点的度:节点拥有的子树的数目。
叶子:度为零的节点。
分支节点:度不为零的节点。
树的度:树中节点的最大的度。
层次:根节点的层次为1,其余节点的层次等于该节点的双亲节点加1。
树的高度:树中节点的最大层次。
无序数:如果树中节点的各子树之间的次序是不重要的,可以交换位置。
有序数:如果树中结点的各子树的次序是重要的,不可以交换位置。
森林:0个或多个不相交的树组成。对森林加上一个跟,森林即成为树;删去跟,树即成为森林。
2.3二叉树的性质
性质1:二叉树第i层上的节点数目最多为 2{i-1} (i≥1)。
性质2:深度为k的二叉树至多有2{k}-1个节点(k>=1)。
性质3:包含n个节点的二叉树的高度至少为log2 (n+1)。
性质4:在任意一颗二叉树中,若终端节点的个数为n0,度为2的节点数为n2,则n0=n2+1。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <math.h>
#define OVERFLOW 1
#define MAX_SIZE 10
typedef struct Btnode_
{
int elem;
Btnode_ *left;
Btnode_ *right;
}Btnode,*btnode;
typedef struct Btnodequeue_
{
btnode *element;
int front;
int rear;
}Btnodequeue,*btnodequeue;
btnodequeue initqueue(){
btnodequeue resultqueue=(btnodequeue)malloc(sizeof(Btnodequeue));
if (!resultqueue)
exit(OVERFLOW);
resultqueue->element=(btnode*)malloc(sizeof(btnode)*MAX_SIZE);
resultqueue->front=0;
resultqueue->rear=1;
return resultqueue;
}
bool isqueueempty(btnodequeue l){
if (l->front+1==l->rear){
return true;
}
return false;
}
btnodequeue enqueue(btnode bt,btnodequeue l){
if ((l->front+1)%MAX_SIZE==(l->rear)%MAX_SIZE && l->front+1!=l->rear){
printf("空间已满\n");
exit(OVERFLOW);
}
l->element[l->rear]=bt;
l->rear++;
return l;
}
btnode outnode(btnodequeue l){
if (l->front+1==l->rear){
printf("队列为空!\n");
exit(OVERFLOW);
}
return l->element[l->front+1];
}
btnodequeue outqueue(btnodequeue l){
if (l->front+1==l->rear){
printf("队列为空!\n");
exit(OVERFLOW);
}
l->front++;
return l;
}
btnode constructnode(int number){
btnode resultnode=(btnode)malloc(sizeof(Btnode));
resultnode->elem=number;
resultnode->right=NULL;
resultnode->left=NULL;
return resultnode;
}
//构建树
btnode stringconstructnode(int *number){
btnodequeue bq=initqueue();
btnode header;
btnode bt1=constructnode(number[0]);
bq=enqueue(bt1,bq);
header=bt1;
int i=1;
btnode bp,brc,blc;
while(!isqueueempty(bq)){
bp=outnode(bq);
bq=outqueue(bq);
if (number[i]==0){
bp->left=NULL;
}
else{
blc=constructnode(number[i]);
bp->left=blc;
bq=enqueue(blc,bq);
}
i++;
if (number[i]==0){
bp->right=NULL;
}
else{
brc=constructnode(number[i]);
bp->right=brc;
bq=enqueue(brc,bq);
}
i++;
}
return header;
}
//先序遍历
void Preordertraversal(btnode l){
if (!l){
return;
}
printf("%d ",l->elem);
Preordertraversal(l->left);
Preordertraversal(l->right);
}
//中序遍历
void Intermediatetraversal(btnode l){
if (!l){
return;
}
Intermediatetraversal(l->left);
printf("%d ",l->elem);
Intermediatetraversal(l->right);
}
//后序遍历
void Postordertraversal(btnode l){
if (!l){
return;
}
Postordertraversal(l->left);
Postordertraversal(l->right);
printf("%d ",l->elem);
}
void testsample(){
//char* tempString = "acde#bf######";
int s[13]={1,2,3,4,0,5,6,0,0,0,0,0,0};
btnode bt=stringconstructnode(s);
printf("先序遍历:");
Preordertraversal(bt);
printf("\r\n");
printf("中序遍历:");
Intermediatetraversal(bt);
printf("\r\n");
printf("后序遍历:");
Postordertraversal(bt);
}
int main(){
testsample();
return 0;
}
运行结果:
总结:
遍历可以说是二叉树最简单的操作, 运用递归的思想可以很简单的完成,而非递归的二叉树构建需要用到队列,通过队列也能够比较简单的达到要求。