打印树,求大神指点
就是把二叉树,按树形结构打印出来,我想了一整天了,还是实现不了,思绪好乱。。。。。代码就不贴了求大神搭救🙏
//二叉树的创建及其遍历程序:字符型结点数据 /* 二叉树的建立与遍历 */ # include <stdio.h> # include <stdlib.h> # include <string.h> # define MAX_NODE 50 # define MaxLine 100 typedef char Etype; typedef struct BiTNode{ /* 树结点结构 */ Etype data; struct BiTNode *lch,*rch; }BiTNode; /********************************************************/ /* 函数原形声明 */ /********************************************************/ //二叉树的创建函数 BiTNode *creat_bt0(); //创建一颗固定的二叉树(实验用,避免多次输入) BiTNode *creat_bt1(); //按完全二叉树编号创建 BiTNode *creat_bt2(); //按先序遍历创建 BiTNode *creat_NewNode(Etype e);//创建二叉树的一个结点 //二叉树的模拟输出 void LevelDSP(BiTNode *p); //层次遍历法显示二叉树 void visitPNode(BiTNode *p, int level); //设置结点所在层的字符串(输出用) //遍历二叉树函数原型申明 void DLR(BiTNode *p); //先序遍历 void LDR(BiTNode *p); //中序遍历 void LRD(BiTNode *p); //后序遍历 void Level(BiTNode *p); //层次遍历 //结点统计函数原型申明 void NodeNumDLR(BiTNode *p); //前序统计结点数 void NodeNumLDR(BiTNode *p); //中序统计结点数 void NodeNumLRD(BiTNode *p); //后序统计结点数 void NodeNumLevel(BiTNode *p); //层次遍历 //计算二叉树的深度 int CNTdepth( BiTNode *p); //计算二叉树的深度 //二叉树的结点访问:输出结点、统计结点 void visitC(Etype dataC); void visitCT(BiTNode *p); //输出结点,统计结点类型n0,n1,n2 //定义全程变量,各种结点数 int n=0,n0=0,n1=0,n2=0; //统计结点用 char Line1[MaxLine],Line2[MaxLine],Line3[MaxLine]; //二叉树模拟输出用 BiTNode *t; /********************************************************/ /* 主函数main */ /********************************************************/ main(){ char ch; int k; do { printf("\n"); printf("\n 0. 结束程序运行\n"); printf("\n 1. 建立二叉树方法1(性质5:完全二叉树编号) "); printf("\n 2. 建立二叉树方法2(先序递归)\n"); printf("\n 3. 先序DLR递归遍历二叉树"); printf("\n 4. 中序LDR递归遍历二叉树"); printf("\n 5. 后序LRD递归遍历二叉树"); printf("\n 6. 层次Level遍历二叉树\n"); printf("\n 7. 先序递归统计树中N0、N1、N2结点个数"); printf("\n 8. 中序递归统计树中N0、N1、N2结点个数"); printf("\n 9. 后序递归统计树中N0、N1、N2结点个数"); printf("\n 10. 后序递归统计树中N0、N1、N2结点个数\n"); printf("\n 11. 计算二叉树的深度\n"); printf("\n 12. 创建固定二叉树"); printf("\n 13. 输出二叉树\n"); printf("\n=================================================="); printf("\n 请输入您的选择 (0,1,2,3,4,5,6,7,8,9,10,11,12,13)"); scanf("%d",&k); switch(k){ case 1:t=creat_bt1( );break; /* 调用性质5建立二叉树算法 */ case 2:t=creat_bt2( );break; /* 调用递归建立二叉树算法 */ case 3: { printf("\n%2d 先序遍历结果是:",k); DLR(t); /* 调用先序遍历 */ } break; case 4: { printf("\n%2d 中序遍历结果是:",k); LDR(t); /* 调用中序遍历 */ } break; case 5: { printf("\n%2d 后序遍历结果是:",k); LRD(t); /* 调用后序遍历 */ } break; case 6: { printf("\n%2d 层次遍历结果是:",k); Level(t); /* 调用后序遍历 */ } break; case 7: { n=0;n0=0 ; n1=0; n2=0; /* 全局变量置0 */ printf("\n %d:先序结果:",k); NodeNumDLR(t); printf("\n 二叉树结点数 n=%d, n0=%d, n1=%d, n2=%d",n,n0,n1,n2); } break; case 8: { printf("\n %d:中序结果:",k); n=0;n0=0 ; n1=0; n2=0; /* 全局变量置0 */ NodeNumLDR(t); printf("\n 二叉树结点数 n=%d, n0=%d, n1=%d, n2=%d",n,n0,n1,n2); } break; case 9: { printf("\n %d:后序结果:",k); n=0;n0=0 ; n1=0; n2=0; /* 全局变量置0 */ NodeNumLRD(t); printf("\n 二叉树结点数 n=%d, n0=%d, n1=%d, n2=%d",n,n0,n1,n2); } break; case 10: { printf("\n %d:层次结果:",k); n=0;n0=0 ; n1=0; n2=0; /* 全局变量置0 */ NodeNumLevel(t); printf("\n 二叉树结点数 n=%d, n0=%d, n1=%d, n2=%d",n,n0,n1,n2); } break; case 11: { printf( "\n 二叉树的深度(层数)是:%d",CNTdepth(t) ); } break; case 12: t=creat_bt0( );break; //建立固定二叉树 case 13: LevelDSP(t); break; //输出二叉树 case 0: exit(0); } /* switch */ }while(k>=0 && k<=13); printf("\n 再见!"); printf("\n 打回车键,返回。"); ch=getchar(); } /* main */ /********************************************************/ /* 二叉树的创建相关函数 */ /********************************************************/ // 创建一个固定结构的二叉树,用于实验,避免多次输入 BiTNode *creat_bt0(){ BiTNode *t,*p,*q; t=(BiTNode *)malloc(sizeof(BiTNode)); t->data='A'; //根结点 A p=creat_NewNode('B');// / \ t->lch=p; // 左孩子 B C q=creat_NewNode('D');// / \ / p->lch=q; // 左孩子 D E F // \ q=creat_NewNode('E'); // G p->rch=q; /* 左孩子 */ p=creat_NewNode('G'); q->rch=p; /* 左孩子 */ p=creat_NewNode('C'); t->rch=p; /* 右孩子 */ q=creat_NewNode('F'); p->lch=q; /* 左孩子 */ //LevelDSP(t); //输出二叉树 return(t); } // creat_bt0 // 利用二叉树性质5(编号i),借助一维数组V 建立二叉树 BiTNode *creat_bt1(){ BiTNode *t,*p,*v[20]; int i,j; Etype e; /* 输入结点的序号i 、结点的数据e */ printf("\n结点数据(格式0?结束)i,char=?"); scanf("%d%c",&i,&e); while(i!=0 && (e!='?' || e!='/')){ /* 当 i ,e都为0时,结束循环 */ p=(BiTNode *)malloc(sizeof(BiTNode)); p->data=e; p->lch=NULL; p->rch=NULL; v[i]=p; if (i==1) t=p; /* 序号为1的结点是根 */ else{ j=i/2; if(i%2==0) v[j]->lch=p; /* 序号为偶数,做左孩子*/ else v[j]->rch=p; /* 序号为奇数,做右孩子*/ } printf("\n结点数据(格式0?结束)i,char=?"); scanf("%d%c",&i,&e); } return(t); } // creat_bt1 // 模仿先序递归遍历方法,建立二叉树 BiTNode *creat_bt2(){ BiTNode *t; Etype e; scanf("%c",&e); //过滤前面菜单选择留下的回车键 printf("\n如连续输入以空格间隔,/结束分支 char="); scanf("%c",&e); if(e=='/' || e=='?') t=NULL; /* 对于0值,不分配新结点 */ else { t=(BiTNode *)malloc(sizeof(BiTNode)); t->data=e; t->lch=creat_bt2(); /* 左孩子获得新指针值 */ t->rch=creat_bt2(); /* 右孩子获得新指针值 */ } return(t); } // creat_bt2 // 创建一个新结点,用于建立二叉树,供creat_bt0()调用 BiTNode *creat_NewNode(Etype e){ BiTNode *t; if(e=='/' || e=='?') t=NULL; /* 对于0值,不分配新结点 */ else { t=(BiTNode *)malloc(sizeof(BiTNode)); t->data=e; t->lch=NULL; /* 左孩子为空指针值 */ t->rch=NULL; /* 右孩子为空指针值 */ } return(t); } // creat_NewNode /********************************************************/ /* 二叉树的遍历相关函数 */ /********************************************************/ // 先序递归遍历二叉树 void DLR(BiTNode *p){ if (p) { visitC(p->data); //访问根节点 DLR(p->lch); //先序遍历左子树 DLR(p->rch); //先序遍历右子树 } } //DLR // 中序递归遍历二叉树 void LDR(BiTNode *p){ if (p) { LDR(p->lch); //中序遍历左子树 visitC(p->data); //访问根节点 LDR(p->rch); //中序遍历右子树 } } //LDR // 后序递归遍历二叉树 void LRD(BiTNode *p){ if (p) { LRD(p->lch); //后序遍历左子树 LRD(p->rch); //后序遍历右子树 visitC(p->data); //访问根节点 } } //LRD //层次遍历二叉树 void Level(BiTNode *p){ //层次遍历 BiTNode *Queue[MAX_NODE]; int front=0 , rear=0 ; if (p!=NULL){ Queue[++rear]=p; /* 根结点入队 */ while (front<rear) { //队列不为空执行循环 p=Queue[++front]; visitC( p->data ); if (p->lch != NULL) Queue[++rear]=p->lch; /* 左结点入队 */ if (p->rch != NULL) Queue[++rear]=p->rch; /* 右结点入队 */ } } } //Level /********************************************************/ /* 二叉树的节点统计相关函数 */ /********************************************************/ /* 利用前序递归遍历二叉树的方法,计算树中结点个数 */ void NodeNumDLR(BiTNode *p){ if (p) { visitCT( p ); //在visit的基础上,增加了统计n,n1,n2功能 NodeNumDLR(p->lch); //前序统计左子树的根结点属于n0,n1,n2 NodeNumDLR(p->rch); //前序统计右子树的根结点属于n0,n1,n2 } } /* NodeNumDLR */ /* 利用中序递归遍历二叉树的方法,计算树中结点个数 */ void NodeNumLDR(BiTNode *p){ if (p) { NodeNumLDR(p->lch); //中序统计左子树的根结点属于n0,n1,n2 visitCT( p ); //在visit的基础上,增加了统计n,n1,n2功能 NodeNumLDR(p->rch); //中序统计右子树的根结点属于n0,n1,n2 } } /* NodeNumLDR */ /* 利用后序递归遍历二叉树的方法,计算树中结点个数 */ void NodeNumLRD(BiTNode *p){ if (p) { NodeNumLRD(p->lch); //后序统计左子树的根结点属于n0,n1,n2 NodeNumLRD(p->rch); //后序统计右子树的根结点属于n0,n1,n2 visitCT( p ); //在visit的基础上,增加了统计n,n1,n2功能 } } /* NodeNumLRD */ //利用层次遍历二叉树的方法,计算树中结点个数 void NodeNumLevel(BiTNode *p){ //层次遍历 BiTNode *Queue[MAX_NODE]; int front=0 , rear=0 ; if (p!=NULL){ Queue[++rear]=p; /* 根结点入队 */ while (front<rear) { //队列不为空执行循环 p=Queue[++front]; visitCT( p ); if (p->lch != NULL) Queue[++rear]=p->lch; /* 左结点入队 */ if (p->rch != NULL) Queue[++rear]=p->rch; /* 右结点入队 */ } } } /* 层次遍历二叉树算法,统计结果 */ /********************************************************/ /* 计算二叉树的深度函数 */ /********************************************************/ //求二叉树的深度(利用层次遍历算法) int CNTdepth( BiTNode *p){ BiTNode *Queue[MAX_NODE+1]; int front=0 , rear=0, depth=0, level ; /* level总是指向访问层的最后一个结点在队列的位置 */ if (p==NULL) return(0); Queue[++rear]=p; /* 根结点入队,rear=1 */ level=rear ; /* 根是第1层的最后一个节点 */ while (front<rear){ //队列不为空 p=Queue[++front]; //出队 if (p->lch!=NULL) Queue[++rear]=p->lch; /* 左结点入队 */ if (p->rch!=NULL) Queue[++rear]=p->rch; /* 右结点入队 */ if (front==level){ /* 正访问的是当前层的最后一个结点 */ depth++ ; level=rear ; }//累计树的深度 } return(depth); } /********************************************************/ /* 二叉树的结点访问相关函数 */ /********************************************************/ //输出结点 void visitC(Etype dataC){ printf("%c ",dataC); } //输出结点并统计结点数 void visitCT(BiTNode *p){ //输出结点,统计结点类型n0,n1,n2 visitC( p->data ); //增加了三类结点统计 n++; if(p->lch==NULL && p->rch==NULL) n0++; //叶子结点 if((p->lch==NULL && p->rch!=NULL) || (p->lch!=NULL && p->rch==NULL)) n1++; //度为1是结点 if(p->lch!=NULL && p->rch!=NULL) n2++; //度为2的结点 } /*********************************************************/ /* 层次遍历法显示二叉树 */ /*********************************************************/ void LevelDSP(BiTNode *p){ //层次遍历法显示二叉树 BiTNode *Queue[MAX_NODE+1]; int front=0 , rear=0, depth=0, level ; /* level总是指向访问层的最后一个结点在队列的位置 */ if (p==NULL) { printf("该树为空树\n"); return; } Queue[++rear]=p; /* 根结点入队,rear=1 */ level=rear ; /* 根是第1层的最后一个节点 */ //为第一层初始化(根结点) // strcpy(Line1,"A23456789012345678 "); //结点行 strcpy(Line1," "); //结点行 // strcpy(Line2,"B234567890123456 "); //左右分支线行 strcpy(Line2," "); //左右分支线行 strcpy(Line3,""); //用于初始化Line1无左或右结点的下一结点行 while (front<rear){ //队列不为空 p=Queue[++front]; //出队 visitPNode( p ,depth); if (p->lch!=NULL) Queue[++rear]=p->lch; /* 左结点入队 */ if (p->rch!=NULL) Queue[++rear]=p->rch; /* 右结点入队 */ if (front==level){ /* 正访问的是当前层的最后一个结点 */ printf("%s\n",Line1); //print Node printf("%s\n",Line2); //print Line depth++ ; level=rear ; switch(depth){ //为下一层初始化字符串,最多允许4层树 case 0:{ //本情况其实无效,在前面已经初始化 // strcpy(Line1,"123456789012345678 "); strcpy(Line1," "); // strcpy(Line2,"1234567890123456 "); strcpy(Line2," "); }break; case 1:{ //第2行 // strcpy(Line1,"12345678901234 "); strcpy(Line1," "); // strcpy(Line2,"123456789012 "); strcpy(Line2," "); }break; case 2:{ //第3行 // strcpy(Line1,"12345678901 "); strcpy(Line1," "); // strcpy(Line2,"1234567890 "); strcpy(Line2," "); }break; case 3:{ //第4行 // strcpy(Line1,"123456789 "); strcpy(Line1," "); // strcpy(Line2,"12345678 "); strcpy(Line2," "); }break; }//end switch strcat(Line1,Line3); strcpy(Line3,""); }//累计树的深度 else{ //用于初始化Line1无左或右结点的下一结点行 // if(! p->lch ) strcat(Line3,"+ "); // if(! p->rch ) strcat(Line3,"- "); if(! p->lch ) strcat(Line3," "); if(! p->rch ) strcat(Line3," "); } } } //LevelDSP //123456789012345678901234567 _A_ //1234567890123456789012345 _/_+_\_ //12345678901234567890123 _B_+++++_C_ //1234567890123456789012 /__\++++++/_\ //12345678901234567890 _D_++_E_++_F_+_G_ //1234567890123456789 _/_\++/_\__/_\++/_\_ //123456789012345678 _H_++I_J__K_L__M_N_+_O_ // //Line1="12345678901234567890",20个空格初始化 //Line2="12345678901234567890",20个空格初始化 //初始化一个结点的显示格式,被LevelDSP调用 void visitPNode(BiTNode *p,int level){ //设置结点所在层的字符串 //参数Level=depth=实际层次-1 char Tmp[2]; // visitC( p->data ); Tmp[0]=p->data;Tmp[1]='\0'; //将字符型的结点值转化成字符串型 strcat(Line1,Tmp); switch(level){ case 0: { //第一层 if(p->lch) strcat(Line2,"/ "); //存在左子树,输出/ else strcat(Line2," "); //无左子树,输出空格 if(p->rch) strcat(Line2,"\\"); //存在右子树,输出\ else strcat(Line2," "); //无右子树,输出空格 }break; case 1: { //第二层 strcat(Line1," "); if(p->lch) strcat(Line2,"/ "); //存在左子树,输出/ else strcat(Line2," "); //无左子树,输出空格 if(p->rch) strcat(Line2,"\\ "); //存在右子树,输出\ else strcat(Line2," "); //无右子树,输出空格 }break; case 2: { //第三层 strcat(Line1," "); if(p->lch) strcat(Line2,"/ "); //存在左子树,输出/ else strcat(Line2," "); //无左子树,输出空格 if(p->rch) strcat(Line2,"\\ "); //存在右子树,输出\ else strcat(Line2," "); //无右子树,输出空格 }break; case 3: { //第四层 strcat(Line1," "); //第四层之后暂时不做处理 /* if(p->lch) strcat(Line2,"/0"); //存在左子树,输出/ else strcat(Line2,"=0"); //无左子树,输出空格 if(p->rch) strcat(Line2,"\\00"); //存在右子树,输出\ else strcat(Line2,"=00"); //无右子树,输出空格 */ }break; } }