上次我们已经讲了,如何将数组转换成一个二叉树,那么当我们已经拥有一个二叉树,我们又可以对二叉树进行什么操作呢,或者说二叉树这种数据结构的优势在哪呢。
//叶子节点
void leaf(BiTree Troot,int cnt){
if(cnt==DataCount) return;
if(Troot->lchild==NULL&&Troot->rchild==NULL){
printf("%d ",Troot->data);
}
if(Troot->lchild) leaf(Troot->lchild,++cnt);
if(Troot->rchild) leaf(Troot->rchild,++cnt);
}
//Dnode的双亲节点
void parents(BiTree Troot,BiTree T){
BiTree Pnodep;
Pnodep = T;
if(Pnodep){
if(Pnodep->lchild==Troot) {
printf("Father:%d\n",Pnodep->data);
Father = Pnodep;
}
else parents(Troot,Pnodep->lchild);
if(Pnodep->rchild ==Troot){
printf("Father:%d\n",Pnodep->data);
Father = Pnodep;
}
else parents(Troot,Pnodep->rchild);
}
}
//中序遍历
void inOrder(BiTree T){
if(T){
inOrder(T->lchild);
printf("%d ",T->data);
inOrder(T->rchild);
}
}
//拷贝二叉树
BiTree Tcopy(BiTree T){
if(!T) return NULL;
BiTree copyt = (BiTree)malloc(sizeof(BiTNode));
copyt->data = T->data;
copyt->lchild = Tcopy(T->lchild);
copyt->rchild = Tcopy(T->rchild);
return copyt;
}
//搜索树中的节点
void search(BiTree Troot,int x){ //查找树中的数字,返回地址。
if(Troot->data==x){
J = 1;
Dnode = Troot;//不要将search的值作为return返回 会出问题的。
return ;
}
else{
if(Troot->lchild) search(Troot->lchild,x);
if(Troot->rchild) search(Troot->rchild,x);
}
if(J==0&&Troot->data==T->data) {
Dnode = NULL;
return;
}
}
//删除节点
void Delete(BiTree Troot,BiTree T1){
BiTree Nodep = NULL;
if(Troot!=NULL){
if(Troot->lchild==NULL&&Troot->rchild==NULL){ //叶子节点delete
Father->lchild = NULL;
Father->rchild = NULL;
}
else if(Troot->lchild!=NULL&&Troot->rchild==NULL){ // 只含有左节点
Troot->data = Troot->lchild->data;
BiTree Nodep1 = Troot->lchild;
if(Nodep1->lchild!=NULL) Troot->lchild = Nodep1->lchild;
else Troot->lchild = NULL;
if(Nodep1->rchild!=NULL) Troot->rchild = Nodep1->rchild;
else Troot->rchild = NULL;
}
else if(Troot->rchild!=NULL&&Troot->lchild==NULL){ // 只含有右节点
Troot->data = Troot->rchild->data;
BiTree Nodep2 = Troot->rchild;
if(Nodep2->rchild!=NULL) Troot->rchild = Nodep2->rchild;
else Troot->rchild = NULL;
if(Nodep2->lchild!=NULL) Troot->lchild = Nodep2->lchild;
else Troot->lchild = NULL;
}
else{ //既含有左节点又含有右节点
Nodep = Troot->rchild;
while(Nodep->lchild!=NULL){
if(Nodep->lchild->lchild==NULL){
break;//Nodep指向大于被删除值的最小值的父节点。
}
Nodep = Nodep->lchild;
}
if(Nodep->lchild==NULL){
Troot->data = Nodep->data;
if(Nodep->rchild!=NULL) Troot->rchild = Nodep->rchild;
}
else{
Troot->data = Nodep->lchild->data;
Nodep->lchild = Nodep->lchild->rchild;
}
}
inOrder(T1);
return;
}
else{
printf("不存在\n");
return;
}
}
//返回深度
int Depth(BiTree T){
int m, n;
if (T == NULL)
return 0; //如果是空树,深度为0,递归结束
else{
m = Depth(T->lchild); //递归计算左子树的深度记为m
n = Depth(T->rchild); //递归计算右子树的深度记为n
if (m > n)
return (m + 1); //二叉树的深度为m 与n的较大者加1
else
return (n + 1);
}
}
值得注意的是其中含有一些全局变量Dnode用于返回被查找节点的地址。