数据结构树的基本操作_数据结构之二叉树的基本操作

这篇博客介绍了二叉树的基本操作,包括如何通过字符串创建二叉树、查找特定节点、获取节点的左右孩子、计算二叉树的深度和宽度、节点个数和叶子节点个数,以及展示不同遍历方式。提供了完整的C语言实现代码。
摘要由CSDN通过智能技术生成

#include#include#include

#define MaxSize 100typedefcharElemType;

typedefstructnode

{

ElemType data;//数据类型

struct node *lchild;//指向左孩子

struct node *rchild;//指向右孩子

}BTNode;void CreateBTNode(BTNode *&b,char *str)//由str串创建二叉链

{

BTNode*St[MaxSize],*p=NULL;int top=-1,k,j=0;charch;

b=NULL;//建立二叉链初始时为空

ch=str[j];while(ch!='\0')//str未扫描完时循环

{switch(ch)

{case'(':top++;St[top]=p;k=1;break;//为左结点

case')':top--;break;case',':k=2;break;//为右结点

default:p=(BTNode *)malloc(sizeof(BTNode));

p->data=ch;

p->lchild=p->rchild=NULL;if(b==NULL)//p指向二叉树的根结点

b=p;else//已建立二叉树根结点

{switch(k)

{case 1:St[top]->lchild=p;break;case 2:St[top]->rchild=p;break;

}

}

}

j++;

ch=str[j];

}

}

BTNode*FindNode(BTNode *b,ElemType x)//返回data域为x的结点指针

{

BTNode*p;if(b==NULL)returnNULL;else if(b->data==x)returnb;else{

p=FindNode(b->lchild,x);if(p!=NULL)returnp;else

return FindNode(b->rchild,x);

}

}

BTNode*LchildNode(BTNode *p)//返回*p结点的左孩子结点指针

{return p->lchild;

}

BTNode*RchildNode(BTNode *p)//返回*p结点的右孩子结点指针

{return p->rchild;

}int BTNodeDepth(BTNode *b)//求二叉树b的深度

{intlchilddep,rchilddep;if(b==NULL)return (0);//空树的深度为0

else{

lchilddep=BTNodeDepth(b->lchild);

rchilddep=BTNodeDepth(b->rchild);return(lchilddep>rchilddep)?(lchilddep+1):(rchilddep+1);

}

}void DispBTNode(BTNode *b)//以括号表示法输出二叉树

{if(b!=NULL)

{

printf("%c",b->data);if(b->lchild!=NULL||b->rchild!=NULL)

{

printf("(");

DispBTNode(b->lchild);if(b->rchild!=NULL) printf(",");

DispBTNode(b->rchild);

printf(")");

}

}

}/*求二叉树的宽度*/

int BTWidth(BTNode *b)

{struct{intlno;

BTNode*p;

}Qu[MaxSize];int front=0,rear=0;intlnum,max,i,n;if(b!=NULL)

{

rear++;

Qu[rear].p=b;

Qu[rear].lno=1;while(rear!=front)

{

front++;

b=Qu[front].p;

lnum=Qu[front].lno;if(b->lchild!=NULL)

{

rear++;

Qu[rear].p=b->lchild;

Qu[rear].lno=lnum+1;

}if(b->rchild!=NULL)

{

rear++;

Qu[rear].p=b->rchild;

Qu[rear].lno=lnum+1;

}

}

max=0;

lnum=1;

i=1;while(i<=rear)

{

n=0;while(i<=rear&&Qu[i].lno==lnum)

{

n++;

i++;

}

lnum=Qu[i].lno;if(n>max)

max=n;

}returnmax;

}else

return 0;

}int Nodes(BTNode *b)//求二叉树b结点的个数

{intnum1,num2;if(b==NULL)//空树的情况

return 0;else if(b->lchild==NULL&&b->rchild==NULL)//为叶子结点的情况

return 1;else//其他情况

{

num1=Nodes(b->lchild);

num2=Nodes(b->rchild);return (num1+num2+1);//返回左右树结点树加1

}

}int LeafNodes(BTNode *b)//求二叉树b叶子结点个数

{intnum1,num2;if(b==NULL)//空树的情况

return 0;else if(b->lchild==NULL&&b->rchild==NULL)//为叶子结点的情况

return 1;else//其他情况

{

num1=LeafNodes(b->lchild);

num2=LeafNodes(b->rchild);return (num1+num2);//返回左右子树叶子结点树

}

}void DestroyBTNode(BTNode *&b)

{if(b!=NULL)

{

DestroyBTNode(b->lchild);

DestroyBTNode(b->rchild);

free(b);

}

}//===============================================================//先序递归遍历

void PreOrder(BTNode *b)

{if(b)

{

printf("%c",b->data);

PreOrder(b->lchild);

PreOrder(b->rchild);

}

}//中序递归遍历

void InOrder(BTNode *b)

{if(b)

{

InOrder(b->lchild);

printf("%c",b->data);

InOrder(b->rchild);

}

}//后序递归遍历

void PostOrder(BTNode *b)

{if(b)

{

PostOrder(b->lchild);

PostOrder(b->rchild);

printf("%c",b->data);

}

}//================================================================

void DispLeaf(BTNode * b)//输出叶子节点

{if(b)

{if(b->lchild==NULL&&b->rchild==NULL)

printf("%c",b->data);else{

DispLeaf(b->lchild);

DispLeaf(b->rchild);

}

}

}void AllPath(BTNode *b,ElemType path[],intpathlen)

{inti;if(b)

{if(b->lchild==NULL&&b->rchild==NULL)

{

printf("%c到根节点逆路径:%c",b->data,b->data);for(i=pathlen-1;i>=0;i--)

printf("%c",path[i]);

printf("\n");

}else{

path[pathlen]=b->data;

pathlen++;

AllPath(b->lchild,path,pathlen);

AllPath(b->rchild,path,pathlen);

pathlen--;

}

}

}voidmenu()

{

printf("---------------------------------------------------\n");

printf("(1)输出二叉树\n");

printf("(2)H结点\n");

printf("(3)二叉树b的深度\n");

printf("(4)二叉树b的宽度\n");

printf("(5)二叉树b的结点个数\n");

printf("(6)二叉树b的叶子结点个数\n");

printf("(7)二叉树b的叶子节点\n");

printf("(8)二叉树三种遍历\n");

printf("(9)AllPath \n");

printf("(0)按其他键退出!\n");

printf("---------------------------------------------------\n");

}intmain()

{

BTNode*b,*p,*lp,*rp;

ElemType path[MaxSize];

CreateBTNode(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");while(1){

menu();intn;

printf("请输入您的选项:");

scanf("%d",&n);switch(n)

{case 1:

printf("(1)输出二叉树:");

DispBTNode(b);

printf("\n");break;case 2:

printf("(2)H结点:");

p=FindNode(b,'H');if(p!=NULL)

{

lp=LchildNode(p);if(lp!=NULL)

printf("左孩子为%c",lp->data);elseprintf("无左孩子");

rp=RchildNode(p);if(rp!=NULL)

printf("右孩子为%c",rp->data);elseprintf("无右孩子");

}

printf("\n");break;case 3:

printf("(3)二叉树b的深度:%d\n",BTNodeDepth(b)); break;case 4:

printf("(4)二叉树b的宽度:%d\n",BTWidth(b)); break;case 5:

printf("(5)二叉树b的结点个数:%d\n",Nodes(b)); break;case 6:

printf("(6)二叉树b的叶子结点个数:%d\n",LeafNodes(b)); break;case 7:

printf("(7)二叉树b的叶子结点:");

DispLeaf(b);printf("\n"); break;case 8:

printf("(8)二叉树三种遍历:");

printf("二叉树先序递归遍历:\n");

PreOrder(b);printf("\n");

printf("二叉树中序递归遍历:\n");

InOrder(b);printf("\n");

printf("二叉树后序递归遍历:\n");

PostOrder(b);printf("\n"); break;case 9:

printf("(9)AllPath: \n");

AllPath(b,path,0);default:

printf("Bye~\n");

exit(1);

}

}

printf("释放二叉树b\n");

DestroyBTNode(b);return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值