二叉树基本操作

 

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

#define OK 1
#define NO 0
#define ERROR -1
#define TRUE 1
#define FALSE 0
#define MAXSIZE 50

typedef int Status;

typedef char TElemType;
typedef struct BiTNode
{
TElemType data;
struct BiTNode* lchild;
struct BiTNode* rchild;
}BiTNode;

typedef BiTNode* BiTree;

typedef BiTree SElemType_Sq;
void InitBiTree(BiTree *T);//构造二叉树,初始化二叉树

void ClearBiTree(BiTree *T);//清空二叉树

void DestroyBiTree(BiTree *T);//销毁二叉树

Status BiTreeEmpty(BiTree T);//判断树是否为空

void CreatBitTree(BiTree *T);//按先序序列构造二叉树

int BiTreeLength(BiTree T);//返回二叉树的长度,按完全二叉树计算

int TreeDepth(BiTree T);//返回树的深度(层数)

Status Root(BiTree T,TElemType *e);//返回根结点的值

TElemType Value(BiTree p);//返回某结点的值,p为节点指针

void Assign(BiTree p,TElemType value);//为某结点赋值 !!分析一下 不是需要*p传进去吗 ?里面是对它结构的值进行操作

TElemType Parent(BiTree T,TElemType e);//返回某结点的双亲结点值

TElemType LeftChild(BiTree T,TElemType e);//返回某结点左孩子的值

TElemType RightChild(BiTree T,TElemType e);//返回某结点右孩子的值

TElemType LeftSibling(BiTree T,TElemType e);//返回某结点左兄弟结点的值

TElemType RightSibling(BiTree T,TElemType e);//返回某结点右兄弟结点的值

 

void Leve1orderTraverse_1(BiTree T);//层序遍历二叉树

void PreOrderTraverse_1(BiTree T);//先序遍历二叉树

void InOrderTraverse_1(BiTree T);//中序遍历二叉树

void PostOrderTraverse(BiTree T);//后序遍历二叉树

void PrintTree(BiTree T,int level);

int main(int argc,char **argv)
{
BiTree T ;

printf("1\n函数InitBiTree 测试..\n");
{
printf("初始化一个空二叉树 T..\n");
InitBiTree(&T);//要对T的值进行改变,肯定要传递T的指针进去,因此要用二重指针。
printf("\n");    
}
printf("4\n函数BiTreeEmpty 测试..\n");
{
BiTreeEmpty(T)?printf(" T 为空!!"):printf(" T 不为空!!");
printf("\n");    
}
printf("5\n函数CreatBitTree 测试..\n");
{
printf("按先序序列创建二叉树..\n");
printf("作为示范,录入先序序列:ABDG###EH##I##CF#J###\n");
CreatBitTree(&T);
printf("\n");    
}

/*printf("23\n函数PrintTree 测试..\n");
{
printf("按二叉树结构打印树:T= \n");
PrintTree(T,1);
printf("\n");    
}*/

printf("7\n函数BiTreeDepth 测试..\n");
{
printf("T的深度为%d \n",TreeDepth(T));
printf("\n");    
}
printf("19\n函数Leve1orderTraverse_1 测试..\n");
{
printf("层序遍历二叉树 T = ");
Leve1orderTraverse_1(T);
printf("\n\n");

}
printf("19\n函数PreOrderTraverse_1 测试..\n");
{
printf("先序遍历二叉树1 T = ");
PreOrderTraverse_1(T);
printf("\n\n");

}
printf("19\n函数InOrderTraverse_1 测试..\n");
{
printf("中序遍历二叉树1 T = ");
InOrderTraverse_1(T);
printf("\n\n");

}
printf("19\n函数PostOrderTraverse 测试..\n");
{
printf("后序遍历二叉树 T = ");
PostOrderTraverse(T);
printf("\n\n");

}
printf("8\n函数Root 测试..\n");
{
TElemType e;
Root(T,&e);
printf("T的根结点为:%c \n",e);
printf("\n");


}

printf("9\n函数Value 测试..\n");
{
BiTree p=T->lchild->rchild->lchild;
printf("指针p指向的结点值为%c \n",Value(p));
printf("\n");


}
printf("10\n函数Assign 测试..\n");
{
BiTree p=T->lchild->rchild->lchild;
Assign(p,'X');
printf("将'X'赋给 p 指向的结点后,T = \n");
Leve1orderTraverse_1(T);
printf("\n");


}
printf("11\n函数Parent 测试..\n");
{

printf("'X'结点的双亲为:%c \n",Parent(T,'X'));
printf("\n");


}
printf("12、13\n函数LeftChild、RightChild测试..\n");
{
printf("'E'的左孩子结点值为:%c,右孩子结点值为:%c\n",LeftChild(T,'E'),RightChild(T,'E'));
printf("\n");    
}
printf("14\n函数LeftSibling测试..\n");
{
printf("'I'的左兄弟值为:%c",LeftSibling(T,'I'));
printf("\n");    
}
printf("15\n函数RightSibling测试..\n");
{
printf("'X'的右兄弟值为:%c",RightSibling(T,'X'));
printf("\n");    
}
printf("2\n函数ClearBiTree 测试..\n");
{
ClearBiTree(&T);
if(BiTreeEmpty(T))
printf("T 已被清空!\n");
printf("\n");


}


return 0;

}


void InitBiTree(BiTree *T){
*T=NULL;

}

Status BiTreeEmpty(BiTree T){
return T==NULL?TRUE:FALSE;

}

void ClearBiTree(BiTree *T){
if(*T)
{
if((*T)->lchild)
ClearBiTree(&((*T)->lchild));
if((*T)->rchild)
ClearBiTree(&((*T)->rchild));
free(*T);
*T=NULL;

}


}

 

void CreatBitTree(BiTree *T){
char ch;
scanf("%c",&ch);
if(ch=='#')
*T=NULL;
else
{
*T=(BiTree)malloc(sizeof(BiTNode));
if(!(*T))
exit(-1);
(*T)->data=ch;
CreatBitTree(&(*T)->lchild);
CreatBitTree(&(*T)->rchild);

}

}


int TreeDepth(BiTree T){
if(T==NULL){
return 0;
}
int nLeft=TreeDepth(T->lchild);
int nRight=TreeDepth(T->rchild);
return nLeft>nRight?nLeft+1:nRight+1;

/*****************************************************************************************
*首先如果树T是空的话,就返回深度为0,否则求该树的左孩子的深度和右孩子的深度,两者相互比较*
*返回一个较大的值,递归的最后一层返回的是0值,遇到NULL说明是第0层,最后必然是两个NULL因此*
*碰到叶子之后叶子返回的是1.然后一层层递归回去。 *
******************************************************************************************/
}

void Leve1orderTraverse_1(BiTree T){
int i,j;
BiTree p[100];
i=j=0;
if(T)
p[j++]=T;//如果T存在那么就p[j]指向T并且j++;
while(i<j) //j在每一次取值之后就会比原先+1;j比i要多出来的数值就是结点的个数,j从0开始赋值,而j++作为其最后的状态,并没有值。
{
printf("%c ",p[i]->data);//相当于按顺序输出数组的元素
if(p[i]->lchild)
p[j++]=p[i]->lchild;//将存在的结点按照顺输入到数组中
if(p[i]->rchild)
p[j++]=p[i]->rchild;
i++;

}

}


void PreOrderTraverse_1(BiTree T){
if(T)
{
printf("%c ",T->data);
PreOrderTraverse_1(T->lchild);
PreOrderTraverse_1(T->rchild);

}

}

void InOrderTraverse_1(BiTree T){
if(T){
InOrderTraverse_1(T->lchild);
printf("%c ",T->data);
InOrderTraverse_1(T->rchild);

}


}
void PostOrderTraverse(BiTree T){
if(T){
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c ",T->data);


}


}

Status Root(BiTree T,TElemType *e){
if(!T)
return ERROR;
else
{
*e=T->data;
return OK;

}

 

}

TElemType Value(BiTree p){
return p->data;

}

void Assign(BiTree p,TElemType value){
p->data=value;

}

TElemType Parent(BiTree T,TElemType e){
/**************************************************************************************************************
*parent的实现方法: *
*    从root出发,先求各个结点的左孩子,并且判断是否是要求的X的父亲,将每个经过的左结点放在一个数组中node[0]……*
*    然后判断到最后一个左结点,而其没有左孩子的时候,结束循环,并且在循环的过程中,将每一个不符合的结点的左孩子*
*    置为NULL,这样后来经过这些结点的时候就不会再重新进入循环,同时这也作为判断该节点是否是符合条件的附件的判据*
*    之一(另一个是右孩子)。然后进入第二个if语句,如果最左边的叶子的右孩子存在,那么用node[i+1]将其标记,并且 *
*    将node[i]的右孩子置为空,这时候相当于去除了这个结点,它不符合条件。然后新的node作为循环的起始点,继续进行 *
*    判断。 *
*    而若右结点不存在,即为NULL,这个时候它的孩子肯定也是NULL,因此不影响判断的进行,同时将node[i]标记。然后i--*
*    返回上一层由于node[i]都被标记因此,i--继续返回上一个结点,然后对node[i-1]的右结点进行判断,迭代一直到root *
* i的作用:起到控制循环次数,终止循环的作用 *
***************************************************************************************************************/
BiTNode node[100];
int i=0;
if(T==NULL||(T!=NULL&&e==T->data))
return '\0';
node[i]=*T;
while(i>=0)
{
while(node[i].lchild)
{
if(node[i].lchild->data==e)
return node[i].data;
node[i+1]=*(node[i].lchild);
node[i].lchild=NULL;
i++;

} 
if(node[i].rchild)
{
if(node[i].rchild->data==e)
return node[i].data;
node[i+1]=*(node[i].rchild);
node[i].rchild=NULL;
i++;


}
if(node[i].lchild==NULL&&node[i].rchild==NULL)
i--;

}
if(i<0)//说明元素X不在二叉树中
return '\0';
}

TElemType LeftChild(BiTree T,TElemType e){
/*********************************************************************************************************************************
* LeftChild实现方法: *
*    首先找左边的结点,如果其中某个结点的值就等于要E那么就直接返回它的左孩子,如果没有找到的话,就依次将左边的结点存入node[i]中,*
*    直到node[i]最后没有左孩子为止,这个时候,如果该结点的右孩子存在,那么将右孩子的结点直接赋予node[i+1],可由循环继续进行上述 *
*    判断,并且标记这个时候的node[i]的右孩子也是NULL,相当于去掉这个结点。 * 
*    这个时候判断node[i+1]如果它没有左孩子,也没有右孩子,那么这个时候,就会执行i--然后进行上一个node[i]的判断,由于node[i]的左 *
*    孩子被置为NULL,因此不会进入循环,而是直接判断后面的右孩子是否存在,然后一直迭代到最后。 * 
*********************************************************************************************************************************/
BiTNode node[100];
int i=0;
if(!T)
return '\0';
node[i]=*T;
while(i>=0)
{
while(node[i].data!=e&&node[i].lchild)
{
node[i+1]=*(node[i].lchild);
node[i].lchild=NULL;
i++;
}
if(node[i].data==e)
{
if(node[i].lchild)
return node[i].lchild->data;
else
return '\0';


}
if(node[i].rchild)
{
node[i+1]=*(node[i].rchild);
node[i].rchild=NULL;
i++;
}
if(node[i].lchild==NULL&&node[i].rchild==NULL&&node[i].data!=e)
i--;    

}
if(i<0)
return '\0';

 

}
TElemType RightChild(BiTree T,TElemType e){
BiTNode node[100];
int i=0;
if(!T)
return '\0';
node[i]=*T;
while(i>=0)
{
while(node[i].data!=e&&node[i].lchild)
{
node[i+1]=*(node[i].lchild);
node[i].lchild=NULL;
i++;
}
if(node[i].data==e)
{
if(node[i].lchild)
return node[i].rchild->data;
else
return '\0';


}
if(node[i].rchild)
{
node[i+1]=*(node[i].rchild);
node[i].rchild=NULL;
i++;
}
if(node[i].lchild==NULL&&node[i].rchild==NULL&&node[i].data!=e)
i--;    

}
if(i<0)
return '\0';

 

 


}

TElemType LeftSibling(BiTree T,TElemType e){
BiTNode node[100];
int i=0;
if(((T!=NULL)&&(e==T->data))||T==NULL)
return '\0';


node[i]=*T;
while(i>=0){
while(node[i].rchild)
{
if(node[i].rchild->data==e)
{
if(node[i].lchild)
return node[i].lchild->data;
else 
return '\0';


}
node[i+1]=*(node[i].rchild);
node[i].rchild=NULL;
i++;    

}
if(node[i].lchild)
{
if(node[i].lchild->data==e)
return '\0';
node[i+1]=*(node[i].lchild);
node[i].lchild=NULL;
i++;
}
if(node[i].lchild==NULL&&node[i].rchild==NULL)
i--;
}
if(i<0)
return '\0';
}

TElemType RightSibling(BiTree T,TElemType e){
BiTNode node[100];
int i=0;
if(((T!=NULL)&&(e==T->data))||T==NULL)
return '\0';

node[i]=*T;
while(i>=0){
while(node[i].lchild)
{
if(node[i].lchild->data==e)
{
if(node[i].rchild)
return node[i].rchild->data;
else 
return '\0';


}
node[i+1]=*(node[i].lchild);
node[i].lchild=NULL;
i++;    

}
if(node[i].rchild)
{
if(node[i].rchild->data==e)
return '\0';
node[i+1]=*(node[i].rchild);
node[i].rchild=NULL;
i++;
}
if(node[i].lchild==NULL&&node[i].rchild==NULL)
i--;
}
if(i<0)
return '\0';

 

}

/*
void PrintTree(BiTree T,int level){
int i;
PrintTree(T->rchild,level+1);
for(i=0;i<level;i++)
printf(" ");
printf("%c\n",T->data);
PrintTree(T->lchild,level+1);

}  树状输出一直有些问题,需要再深入思考
*/

//文章参考 http://www.cnblogs.com/kangjianwei101/p/5222014.html

 

posted @ 2017-10-12 21:32  accomplishment  阅读(241)  评论(0编辑  收藏  举报