一、树的创建,输入‘#’节点赋值为NULL。
#include<stdio.h>
#include<stdlib.h>
typedef char datatype;
int maxnum=0;
typedef struct BITREE{
datatype data;
struct BITREE* LChild;
struct BITREE* RChild;
}BTnode,*BTree;
void print(BTree T){
printf("%c ",T->data);
}
void InitBTree(BTree *T){
char ch;
ch=getchar();
if(ch=='#')(*T)=NULL;
else{
(*T)=(BTree)malloc(sizeof(BTnode));
maxnum++;
(*T)->data=ch;
InitBTree(&(*T)->LChild);
InitBTree(&(*T)->RChild);
}
}
二、先序遍历
//先序遍历递归
void PreOrder(BTree T){
if(T==NULL)return;
print(T);
PreOrder(T->LChild);
PreOrder(T->RChild);
}
//先序遍历非递归
void fPreOrder(BTree T){
BTnode* s[maxnum];//创建一个栈空间
int top=-1;//栈指针
while(T!=NULL||top!=-1){
while(T!=NULL){
print(T);
s[++top]=T;
T=T->LChild;
}
if(top!=-1){
T=s[top];
top--;
T=T->RChild;
}
}
}
三、中序遍历
//中序遍历
void InOrder(BTree T){
if(T==NULL)return;
InOrder(T->LChild);
print(T);
InOrder(T->RChild);
}
//中序遍历非递归
void fInOrder(BTree T){
BTnode* s[maxnum];
int top=-1;
while(T!=NULL||top!=-1){
while(T!=NULL){
s[++top]=T;
T=T->LChild;
}
if(top!=-1){
T=s[top];
print(T);
top--;
T=T->RChild;
}
}
}
四、后序遍历
void PostOrder(BTree T){
if(T==NULL){
return;
}
PostOrder(T->LChild);
PostOrder(T->RChild);
print(T);
}
//后序遍历非递归
后序遍历中:二叉树的根节点在其左右子树均遍历完成后才能被访问,所以其非递归方法除了使用和前面两种方法相同的栈意外,还需要另外的栈记录经过某跟节点的次数叉树的根节点在其左右子树均遍历完成后才能被访问。
void fPostOrder(BTree T){
BTnode* s[maxnum];
int top=-1,flag=1,temp[maxnum];//temp栈用来记录当前节点的经过次数,某节点print后,其//temp值变为0.
do{
while(T!=NULL){
s[++top]=T;
temp[top]=1;
T=T->LChild;
}
if(top==-1){
flag=0;
}else{
if(temp[top]==1){
temp[top]=2;
T=s[top];
T=T->RChild;
}else{
T=s[top];
temp[top]=0;
top--;
print(T);
T=NULL;
}
}
}while(flag!=0);
}
五、三种遍历方法的详解,很详细!!!
如图一颗树,先序遍历的结果是:ABCDEFGHK
中序遍历的结果是:BDCAEHGKF
后序遍历的结果是:DCBHKGFEA
以中序遍历为例:A是跟节点,遍历A的左子树
A的左子树存在,找到B,此时B看作根节点,遍历左子树
B的左子树不存在,return到B,print(B),然后遍历B的右子树
B的右子树存在,找到C,此时C看作根节点,遍历左子树
C的左子树存在,找到D,D是叶子节点,print(D),return到C,print(C),然后遍历C的右子树。
C的右子树不存在,return到B,return到A,print(A),然后遍历A的右子树
A的右子树存在,找到E,遍历E的左子树
E的左子树不存在,return到E,print(E),然后遍历E的右子树
E的右子树存在,找到F,遍历F的左子树
F的左子树存在,找到G,遍历G的左子树
G的左子树存在,找到H,H是叶子节点,先print(H),左右节点不存在,return到G
Print(G),遍历G的右子树
G的右子树存在,找到K,K是叶子节点,先print(K),左右节点不存在,return到G,return到F,Print(F),遍历F的右子树
六、找叶子节点
int CountLeaf(BTree T){
BTnode* s[maxnum];
int top=-1,count=0;
while(T!=NULL||top!=-1){
while(T!=NULL){
s[++top]=T;
T=T->LChild;
}
if(top!=-1){
T=s[top];
if(T->RChild==NULL){
count++;
top--;
T=NULL;
}else{
top--;
T=T->RChild;
}
}
}
return count;
}
七、查找元素
BTnode* Search(BTree T,datatype x){
BTnode* q[maxnum];
int front=-1,rear=0;
if(T==NULL)return NULL;
q[rear]=T;
while(front<rear){
if(q[++front]->data==x)return q[++front];
if(q[front]->LChild!=NULL){
q[++rear]=q[front]->LChild;
}
if(q[front]->RChild!=NULL){
q[++rear]=q[front]->RChild;
}
}
return NULL;
}
八、main函数测试
int main(){
BTree T;
BTree S;
printf("创建一颗二叉树:\n");
InitBTree(&T);
printf("先序遍历结果为:\n");
PreOrder(T);//调用先序遍历递归函数
printf("\n");
fPreOrder(T);//调用先序遍历非递归函数
printf("\n");
printf("中序遍历结果为:\n");
InOrder(T);//调用中序遍历递归函数
printf("\n");
fInOrder(T);//调用中序遍历非递归函数
printf("\n");
printf("后序遍历结果为:\n");
PostOrder(T);//调用后序遍历递归函数
printf("\n");
fPostOrder(T);//调用后序遍历非递归函数
printf("\n");
printf("层次遍历结果为:\n");
LevelOrder(T);//调用层序遍历函数
printf("\n\n");
printf("叶子数:%d\n",CountLeaf(T));
printf("这棵树的深度:%d\n\n",deepth(T));
}
目录