文章目录
- ⭐️写在前面的话⭐️
- 二叉树的一些基本操作
- 1、结构定义
- 2、先序创建这棵树
- 3、按满二叉树方式创建
- 4、三种递归遍历
- 5、层次遍历
- 6、求二叉树的深度
- 7、求叶子结点数
- 8、三种非递归遍历
- 9、先序线索化二叉树
- 10、先序线索化后遍历
- 11、中序线索化二叉树
- 12、中序线索化后遍历
- 主函数
- 程序源码
- 运行截图
⭐️写在前面的话⭐️
📒博客主页: 程序员好冰
🎉欢迎 【点赞👍 关注🔎 收藏⭐️ 留言📝】
📌本文由 程序员好冰 原创,CSDN 首发!
📆入站时间: 🌴2022 年 07 月 13 日🌴
✉️ 是非不入松风耳,花落花开只读书。
💭推荐书籍:📚《Java编程思想》,📚《Java 核心技术卷》
💬参考在线编程网站:🌐牛客网🌐力扣
🍭 作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!🍭
二叉树的一些基本操作
1、结构定义
#include <stdio.h>
#include <stdlib.h>#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1#define Nil '#'#define MAX_SIZE 1024typedef int Status;
typedef char ElemType;typedef struct BiTNode
{ElemType data;struct BiTNode *LChild,*RChild;/*左标志,0为指向左子节点,1为指向前驱(即线索)右标志,0为指向右子节点,1为指向后继(即线索)*/int Ltag,Rtag;//供线索化二叉树使用
}BiTNode,*BiTree;
2、先序创建这棵树
void PreCreateBiTree(BiTree *T)
{ElemType ch;getchar();ch=getchar();if(ch==Nil){*T=NULL;//说明这棵子树为空}if(ch!=Nil){*T=(BiTree)malloc(sizeof(BiTNode));(*T)->data=ch;/*线索化线索化二叉树增加的*/(*T)->Ltag=(*T)->Rtag=0;PreCreateBiTree(&((*T)->LChild));PreCreateBiTree(&((*T)->RChild));}
}
3、按满二叉树方式创建
void FullCreateBiTree(BiTree *T)
{BiTNode *p;BiTNode *arr[MAX_SIZE];char ch;int i,j;while(1){scanf("%d",&i);getchar();if(i==0){break;}if(i!=0){ch=getchar();if(ch==Nil){continue;}p=(BiTNode*)malloc(sizeof(BiTNode));p->data=ch;p->Ltag=p->Rtag=0;p->LChild=NULL;p->RChild=NULL;arr[i]=p;if(i==1){*T=p;}if(i!=1){j=i/2;if(i%2==0){arr[j]->LChild=p;}if(i%2!=0){arr[j]->RChild=p;}}}}
}
4、三种递归遍历
//先序递归遍历
void PreOrderTraverse(BiTree T)
{if(T==NULL){return;}printf("%c ",T->data);PreOrderTraverse(T->LChild);PreOrderTraverse(T->RChild);
}//中序递归遍历
void InOrderTraverse(BiTree T)
{if(T==NULL){return;}InOrderTraverse(T->LChild);printf("%c ",T->data);InOrderTraverse(T->RChild);
}//后序递归遍历
void PostOrderTraverse(BiTree T)
{if(T==NULL){return;}PostOrderTraverse(T->LChild);PostOrderTraverse(T->RChild);printf("%c ",T->data);
}
5、层次遍历
/*构建队列*/
int front=0,rear=0;
void EnQueue(BiTree *t,BiTree node)
{//结点入队if(rear==MAX_SIZE){exit(0);}t[rear++]=node;
}
BiTNode* DeQueue(BiTree *t)
{//结点出队if(front==rear){exit(0);}return t[front++];
}
void LevelOrderTraverse(BiTree T)
{if(T){BiTree t[MAX_SIZE]={0};BiTNode *p=NULL;p=T;EnQueue(t,p);while(front<rear){p=DeQueue(t);printf("%c ",p->data);if(p->LChild){EnQueue(t,p->LChild);}if(p->RChild){EnQueue(t,p->RChild);}}}
}
6、求二叉树的深度
int BiTreeDepth(BiTree T)
{int left=0,right=0;if(!T){return 0;}if(T->LChild){left=BiTreeDepth(T->LChild);}if(T->RChild){right=BiTreeDepth(T->RChild);}return left>right?left+1:right+1;
}
7、求叶子结点数
int Count_Leaves(BiTree T)
{if(!T){return 0;}if(!(T->LChild)&&!(T->RChild)){return 1;}return Count_Leaves(T->LChild)+Count_Leaves(T->RChild);
}
8、三种非递归遍历
//先序非递归遍历
void PreOrderTraverse2(BiTree T)
{if(!T){return;}//创建一个数组来模拟栈BiTree stack[MAX_SIZE]={0};int top=-1;stack[++top]=T;while(top>-1){BiTree node=stack[top--];printf("%c ",node->data);if(node->RChild){stack[++top]=node->RChild;}if(node->LChild){stack[++top]=node->LChild;}}
}//中序非递归遍历
void InOrderTraverse2(BiTree T)
{if(!T){return;}BiTree stack[MAX_SIZE]={0};int top=-1;BiTree node=T;while(top>-1||node!=NULL){while(node!=NULL){//一直深入左节点stack[++top]=node;node=node->LChild;}node=stack[top--];printf("%c ",node->data);node=node->RChild;}
}//后序非递归遍历
void PostOrderTraverse2(BiTree T)
{if(!T){return;}BiTree stack1[MAX_SIZE]={0};BiTree stack2[MAX_SIZE]={0};int top1=-1;int top2=-1;BiTree node=T;stack1[++top1]=node;while(top1>-1){node=stack1[top1--];stack2[++top2]=node;if(node->LChild!=NULL){stack1[++top1]=node->LChild;}if(node->RChild!=NULL){stack1[++top1]=node->RChild;}}while(top2>-1){printf("%c ",stack2[top2--]->data);}
}
9、先序线索化二叉树
BiTree pre=NULL;// 全局变量,用于记录前驱节点
void PreOrder_Threading(BiTree T)
{if(T==NULL){return;}if(T->LChild ==NULL){T->Ltag=1;T->LChild=pre;//Ltag为1,指向前驱}if(pre!=NULL && pre->RChild==NULL){pre->Rtag=1;pre->RChild=T;//Rtag为1,指向后继}pre=T;if(T->Ltag==0){PreOrder_Threading(T->LChild);}if(T->Rtag==0){PreOrder_Threading(T->RChild);}
}
10、先序线索化后遍历
void PreOrder_Threading_Traverse(BiTree T)
{BiTree temp=T;while(temp!=NULL){printf("%c ",temp->data);if(temp->Ltag==0){temp=temp->LChild;}else{temp=temp->RChild;//寻找后继}}
}
11、中序线索化二叉树
BiTree pre2=NULL;// 全局变量,用于记录前驱节点
void InOrder_Threading(BiTree T)
{if(T==NULL){return;}if(T->Ltag==0){InOrder_Threading(T->LChild);}//深入到树的最左边的结点if(T->LChild ==NULL){T->Ltag=1;T->LChild=pre2;//Ltag为1,指向前驱}if(pre2!=NULL && pre2->RChild==NULL){pre2->Rtag=1;pre2->RChild=T;//Rtag为1,指向后继}pre2=T;if(T->Rtag==0){InOrder_Threading(T->RChild);}
}
12、中序线索化后遍历
void InOrder_Threading_Traverse(BiTree T)
{BiTree p=T;while(p){while(p->Ltag==0){p=p->LChild;}//深入到最左边的结点printf("%c ",p->data);while(p->Rtag==1&&p->RChild!=NULL){//p->RChild!=NULL说明不是最后一个结点,这个接地那没有后继,指向NULLp=p->RChild;//找到后继节点printf("%c ",p->data);}p=p->RChild;}
}
主函数
int main()
{BiTree T;int flag;printf("请输入需要的创建方式(1为先序,2为满二叉):");scanf("%d",&flag);switch(flag){case 1://先序创建这棵树printf("按先序方式创建这棵树pre_T('#'表示空):\n");PreCreateBiTree(&T);printf("成功.\n");break;case 2://按满二叉树方式创建printf("按满二叉树方式创建这棵树full_T(以 1 A 为输入0结束例):\n");FullCreateBiTree(&T);printf("成功.\n");break;default:printf("你输入的序号有误.\n");break;}//递归遍历(三种:前中后)printf("先序递归的结果:");PreOrderTraverse(T);printf("\n");printf("成功.\n");printf("中序递归的结果:");InOrderTraverse(T);printf("\n");printf("成功.\n");printf("后序递归的结果:");PostOrderTraverse(T);printf("\n");printf("成功.\n");//非递归遍历(三种:前中后)printf("先序非递归的结果:");PreOrderTraverse2(T);printf("\n");printf("成功.\n");printf("中序非递归的结果:");InOrderTraverse2(T);printf("\n");printf("成功.\n");printf("后序非递归的结果:");PostOrderTraverse2(T);printf("\n");printf("成功.\n");//层次遍历printf("层序遍历的结果:");LevelOrderTraverse(T);printf("\n");printf("成功.\n");//求叶子结点数printf("这棵树的叶子结点数为:%d.\n",Count_Leaves(T));//求二叉树的深度printf("这棵树的深度为:%d.\n",BiTreeDepth(T));printf("================\n");printf("1、先序线索化.\n");printf("2、中序线索化.\n");printf("请输入需要线索化的形式:");int flag2;scanf("%d",&flag2);switch(flag2){case 1://先序线索化二叉树并遍历PreOrder_Threading(T);printf("先序线索化二叉树并遍历,结果为:");PreOrder_Threading_Traverse(T);break;case 2://中序线索化二叉树并遍历InOrder_Threading(T);printf("中序线索化二叉树并遍历,结果为:");InOrder_Threading_Traverse(T);break;default:printf("你输入的序号有误.\n");break;}return 0;
}
程序源码
#include <stdio.h>
#include <stdlib.h>#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1#define Nil '#'#define MAX_SIZE 1024typedef int Status;
typedef char ElemType;typedef struct BiTNode
{ElemType data;struct BiTNode *LChild,*RChild;/*左标志,0为指向左子节点,1为指向前驱(即线索)右标志,0为指向右子节点,1为指向后继(即线索)*/int Ltag,Rtag;//供线索化二叉树使用
}BiTNode,*BiTree;//先序创建这棵树
void PreCreateBiTree(BiTree *T)
{ElemType ch;getchar();ch=getchar();if(ch==Nil){*T=NULL;//说明这棵子树为空}if(ch!=Nil){*T=(BiTree)malloc(sizeof(BiTNode));(*T)->data=ch;/*线索化线索化二叉树增加的*/(*T)->Ltag=(*T)->Rtag=0;PreCreateBiTree(&((*T)->LChild));PreCreateBiTree(&((*T)->RChild));}
}//按满二叉树方式创建
void FullCreateBiTree(BiTree *T)
{BiTNode *p;BiTNode *arr[MAX_SIZE];char ch;int i,j;while(1){scanf("%d",&i);getchar();if(i==0){break;}if(i!=0){ch=getchar();if(ch==Nil){continue;}p=(BiTNode*)malloc(sizeof(BiTNode));p->data=ch;p->Ltag=p->Rtag=0;p->LChild=NULL;p->RChild=NULL;arr[i]=p;if(i==1){*T=p;}if(i!=1){j=i/2;if(i%2==0){arr[j]->LChild=p;}if(i%2!=0){arr[j]->RChild=p;}}}}
}//先序递归遍历
void PreOrderTraverse(BiTree T)
{if(T==NULL){return;}printf("%c ",T->data);PreOrderTraverse(T->LChild);PreOrderTraverse(T->RChild);
}//中序递归遍历
void InOrderTraverse(BiTree T)
{if(T==NULL){return;}InOrderTraverse(T->LChild);printf("%c ",T->data);InOrderTraverse(T->RChild);
}//后序递归遍历
void PostOrderTraverse(BiTree T)
{if(T==NULL){return;}PostOrderTraverse(T->LChild);PostOrderTraverse(T->RChild);printf("%c ",T->data);
}//层次遍历
/*构建队列*/
int front=0,rear=0;
void EnQueue(BiTree *t,BiTree node)
{//结点入队if(rear==MAX_SIZE){exit(0);}t[rear++]=node;
}
BiTNode* DeQueue(BiTree *t)
{//结点出队if(front==rear){exit(0);}return t[front++];
}
void LevelOrderTraverse(BiTree T)
{if(T){BiTree t[MAX_SIZE]={0};BiTNode *p=NULL;p=T;EnQueue(t,p);while(front<rear){p=DeQueue(t);printf("%c ",p->data);if(p->LChild){EnQueue(t,p->LChild);}if(p->RChild){EnQueue(t,p->RChild);}}}
}//求二叉树的深度
int BiTreeDepth(BiTree T)
{int left=0,right=0;if(!T){return 0;}if(T->LChild){left=BiTreeDepth(T->LChild);}if(T->RChild){right=BiTreeDepth(T->RChild);}return left>right?left+1:right+1;
}//求叶子结点数
int Count_Leaves(BiTree T)
{if(!T){return 0;}if(!(T->LChild)&&!(T->RChild)){return 1;}return Count_Leaves(T->LChild)+Count_Leaves(T->RChild);
}//先序非递归遍历
void PreOrderTraverse2(BiTree T)
{if(!T){return;}//创建一个数组来模拟栈BiTree stack[MAX_SIZE]={0};int top=-1;stack[++top]=T;while(top>-1){BiTree node=stack[top--];printf("%c ",node->data);if(node->RChild){stack[++top]=node->RChild;}if(node->LChild){stack[++top]=node->LChild;}}
}//中序非递归遍历
void InOrderTraverse2(BiTree T)
{if(!T){return;}BiTree stack[MAX_SIZE]={0};int top=-1;BiTree node=T;while(top>-1||node!=NULL){while(node!=NULL){//一直深入左节点stack[++top]=node;node=node->LChild;}node=stack[top--];printf("%c ",node->data);node=node->RChild;}
}//后序非递归遍历
void PostOrderTraverse2(BiTree T)
{if(!T){return;}BiTree stack1[MAX_SIZE]={0};BiTree stack2[MAX_SIZE]={0};int top1=-1;int top2=-1;BiTree node=T;stack1[++top1]=node;while(top1>-1){node=stack1[top1--];stack2[++top2]=node;if(node->LChild!=NULL){stack1[++top1]=node->LChild;}if(node->RChild!=NULL){stack1[++top1]=node->RChild;}}while(top2>-1){printf("%c ",stack2[top2--]->data);}
}/*=======================================================================*///先序线索化二叉树
BiTree pre=NULL;// 全局变量,用于记录前驱节点
void PreOrder_Threading(BiTree T)
{if(T==NULL){return;}if(T->LChild ==NULL){T->Ltag=1;T->LChild=pre;//Ltag为1,指向前驱}if(pre!=NULL && pre->RChild==NULL){pre->Rtag=1;pre->RChild=T;//Rtag为1,指向后继}pre=T;if(T->Ltag==0){PreOrder_Threading(T->LChild);}if(T->Rtag==0){PreOrder_Threading(T->RChild);}
}//先序线索化后遍历
void PreOrder_Threading_Traverse(BiTree T)
{BiTree temp=T;while(temp!=NULL){printf("%c ",temp->data);if(temp->Ltag==0){temp=temp->LChild;}else{temp=temp->RChild;//寻找后继}}
}/*=======================================================================*///中序线索化二叉树
BiTree pre2=NULL;// 全局变量,用于记录前驱节点
void InOrder_Threading(BiTree T)
{if(T==NULL){return;}if(T->Ltag==0){InOrder_Threading(T->LChild);}//深入到树的最左边的结点if(T->LChild ==NULL){T->Ltag=1;T->LChild=pre2;//Ltag为1,指向前驱}if(pre2!=NULL && pre2->RChild==NULL){pre2->Rtag=1;pre2->RChild=T;//Rtag为1,指向后继}pre2=T;if(T->Rtag==0){InOrder_Threading(T->RChild);}
}//中序线索化后遍历
void InOrder_Threading_Traverse(BiTree T)
{BiTree p=T;while(p){while(p->Ltag==0){p=p->LChild;}//深入到最左边的结点printf("%c ",p->data);while(p->Rtag==1&&p->RChild!=NULL){//p->RChild!=NULL说明不是最后一个结点,这个接地那没有后继,指向NULLp=p->RChild;//找到后继节点printf("%c ",p->data);}p=p->RChild;}
}/*=======================================================================*/int main()
{BiTree T;int flag;printf("请输入需要的创建方式(1为先序,2为满二叉):");scanf("%d",&flag);switch(flag){case 1://先序创建这棵树printf("按先序方式创建这棵树pre_T('#'表示空):\n");PreCreateBiTree(&T);printf("成功.\n");break;case 2://按满二叉树方式创建printf("按满二叉树方式创建这棵树full_T(以 1 A 为输入0结束例):\n");FullCreateBiTree(&T);printf("成功.\n");break;default:printf("你输入的序号有误.\n");break;}//递归遍历(三种:前中后)printf("先序递归的结果:");PreOrderTraverse(T);printf("\n");printf("成功.\n");printf("中序递归的结果:");InOrderTraverse(T);printf("\n");printf("成功.\n");printf("后序递归的结果:");PostOrderTraverse(T);printf("\n");printf("成功.\n");//非递归遍历(三种:前中后)printf("先序非递归的结果:");PreOrderTraverse2(T);printf("\n");printf("成功.\n");printf("中序非递归的结果:");InOrderTraverse2(T);printf("\n");printf("成功.\n");printf("后序非递归的结果:");PostOrderTraverse2(T);printf("\n");printf("成功.\n");//层次遍历printf("层序遍历的结果:");LevelOrderTraverse(T);printf("\n");printf("成功.\n");//求叶子结点数printf("这棵树的叶子结点数为:%d.\n",Count_Leaves(T));//求二叉树的深度printf("这棵树的深度为:%d.\n",BiTreeDepth(T));printf("================\n");printf("1、先序线索化.\n");printf("2、中序线索化.\n");printf("请输入需要线索化的形式:");int flag2;scanf("%d",&flag2);switch(flag2){case 1://先序线索化二叉树并遍历PreOrder_Threading(T);printf("先序线索化二叉树并遍历,结果为:");PreOrder_Threading_Traverse(T);break;case 2://中序线索化二叉树并遍历InOrder_Threading(T);printf("中序线索化二叉树并遍历,结果为:");InOrder_Threading_Traverse(T);break;default:printf("你输入的序号有误.\n");break;}return 0;
}
运行截图
🚀先看后赞,养成习惯!🚀
🚀 先看后赞,养成习惯!🚀
🎈觉得文章写得不错的老铁们,点赞评论关注走一波!谢谢啦!🎈