定义:
二叉树是一种每个结点至多有两棵子树(即每个结点的度最大为 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#include #include #include #include #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("rn"); printf("中序遍历:"); Intermediatetraversal(bt); printf("rn"); printf("后序遍历:"); Postordertraversal(bt); } int main(){ testsample(); return 0; }
运行结果:
总结:
遍历可以说是二叉树最简单的操作, 运用递归的思想可以很简单的完成,而非递归的二叉树构建需要用到队列,通过队列也能够比较简单的达到要求。



