二叉树的几个基本算法
来源:互联网 发布:知乎启动画面 编辑:程序博客网 时间:2024/06/11 12:59
二叉树的基本算法
1.二叉树的基本遍历算法(先序、中序、后序、层序)
2.二叉树的优化遍历算法(用栈实现)
3.求二叉树的深度算法
4.求二叉树的宽度算法
5.二叉树的构建算法
#include <stdio.h>#include <stdlib.h>/** * 二叉树的基本算法* 1.二叉树的基本遍历算法(先序、中序、后序、层序)* 2.二叉树的优化遍历算法(用栈实现)* 3.求二叉树的深度算法* 4.求二叉树的宽度算法* 5.二叉树的构建算法**/typedef struct BTNode{ int data; struct BTNode * lchild; struct BTNode * rchild;}BTNode;/*** 二叉树的三种遍历算法* 1.先序、中序、后序、层序*///先序void Trave1(BTNode * root){ if(root != NULL){ printf("%d",root->data); Trave1(root ->lchild); Trave1(root ->rchild); }}//中序void Trave2(BTNode * root){ if(root != NULL){ Trave2(root ->lchild); printf("%d",root->data); Trave2(root -> rchild); }}//后序void Trave3(BTNode * root){ if(root != NULL){ Trave3(root->lchild); Trave3(root->rchild); printf("%d",root->data); }}#define maxSize 100//二叉树的层序列遍历void Trave4(BTNode * root){ //用一个队列辅助遍历二叉树,左孩子和右孩子分别入队 BTNode * que[maxSize]; int front = 0,rear = 0; if(root != NULL){ //根结点入队 rear = (rear + 1)%maxSize; que[rear] = root; while(front != rear){//队列不空则循环 //出队 front = (front +1)%maxSize; printf("%d",que[front]->data); //左右孩子进栈 if(que[front]->lchild != NULL){ rear = (rear + 1)%maxSize; que[rear] = que[front]->lchild; } if(que[front]->rchild != NULL){ rear = (rear + 1)%maxSize; que[rear] = que[front]->rchild; } } } }/*** 二叉树的构建算法,通过'-1'表示结尾* 思路:每次构建完成一个结点,返回结构体指针*/BTNode * createTree(){ printf("请输入一个结点作为二叉树的一个结点\n"); int data; scanf("%d",&data); if(data == -1){ return NULL; }else{ BTNode * root = (BTNode *)malloc(sizeof(BTNode)); root->data = data; root -> lchild = createTree(); root -> rchild = createTree(); return root; }}/*** 求二叉树的深度算法* 思路:分别求二叉树的左右子树的深度,然后再加+1就是总深度,用递归算法即可完成*/int getDepth(BTNode * root){ int ldepth,rdepth; if(root == NULL){ return 0; }else{ ldepth = getDepth(root->lchild); rdepth = getDepth(root->rchild); return (ldepth>rdepth?ldepth:rdepth) + 1; }}/*** 求二叉树的宽度算法* 思路:用层序遍历,将二叉树每层都标上号码,然后用迭代对其进行求最大值* 标号的方式,这里我采用构建一个新的结构体,并定义一个队列数组来进行对每个结点标号* 并且假设这个数组能够容纳下所有结点,这样才能方便在后面的迭代中求最大值*/typedef struct{ BTNode * node; int flag; //层号从1开始到n}ST;int getWidth(BTNode * root){ //先构建一个顺序队列 ST * que[maxSize]; int front=0,rear=0; int flag = 1; if(root != NULL){ //根节点入队,并标号为1,表示第1层 ST * p = (ST *)malloc(sizeof(ST)); p->flag = flag; p->node = root; rear ++; que[rear] = p; BTNode * q; while(root != NULL){ front ++; //这里出队,但是数据元素还是在数组中 q = que[front]->node; if(que[front]->flag > flag){ //证明到达了下一层,那么flag也要增加,这里改写层flag = que[front]->flag也可以 flag ++; } if(que[front]->node->lchild != NULL){ //左孩子不空,则左孩子入队 rear ++; /* que[rear]->node = q->lchild; que[rear]->flag = flag + 1; */ p = (ST *)malloc(sizeof(ST)); p->node = q->lchild; p->flag = flag + 1; que[rear] = p; } if(que[front]->node->rchild != NULL){ rear ++; /* que[rear]->node = q->rchild; que[rear]->flag = flag + 1; */ p = (ST *)malloc(sizeof(ST)); p->node = q->rchild; p->flag = flag + 1; que[rear] = p; } } //下面求二叉树的最大宽度 int i,j,max=0; for(i=1;i<=flag;i++){ int n=0; for(j=1;j<=rear;j++){ if(que[j]->flag == i){ n++; } } if(max<n){ max = n; } } return max; } return 0;}//不使用指针数组int getWidth2(BTNode * root){ ST que[maxSize]; int flag = 1; int front=0,rear=0; if(root !=NULL){ rear ++; que[rear].node = root; que[rear].flag = flag; BTNode * q; while(front != rear){ front ++; q = que[front].node; flag = que[front].flag; if(q->lchild != NULL){ rear ++; que[rear].node = q; que[flag].flag = flag + 1; } if(q->rchild != NULL){ rear ++; que[rear].node = q; que[flag].flag = flag + 1; } } int max,n,i,j; for(i=1;i<=flag;i++){ n = 0; for(j=1;j<=flag;j++){ if(que[j].flag == i){ n++; } } if(max<n){ max = n; } } return max; } return 0;}/*** 用栈实现二叉树的先序遍历* 思路:先序遍历的特点是遇到就输出,分别遍历其左右子树*/void traveByStack(BTNode * root){ BTNode * stack[maxSize]; BTNode * p; int top = -1; if(root != NULL){ //根节点入栈 stack[top] = root; while(top != -1){ //栈不空则循环 //出栈 p = stack[top--]; printf("%d",p->data); if(p->rchild!=NULL){//右孩子不空,则右孩子入栈 stack[++top] = p->rchild; } if(p->lchild!=NULL){//左孩子不空,则左孩子入栈,这里顺序跌倒的原因是因为在栈的输出中顺序是相反的 stack[++top] = p->lchild; } } }}/*** 用栈实现二叉树的中序遍历* 思路:中序的实现根先序列有点不一样,不一样的地方在于,中序需要让左孩子先全进栈,直到没有左孩子就出栈并输出* 出栈之后,将指针移向右孩子,那么就看他有没有右孩子,如果有右孩子,右孩子入栈,重复上面的操作* 否则,就回滚,注意,回滚之后,循环条件又会判断是否还有左孩子,那么由于之前的指针是指向的p的右孩子,所以,这里* 循环进入不了,直接判断是否栈空,栈不空就出栈,并让指针指向出栈元素的右孩子*/void traveByStack2(BTNode * root){ BTNode * stack[maxSize]; int top = -1; BTNode * p = root; //根结点入栈 if(root != NULL){ /* 由于下面的循环写成 || p != NULL 所以这里可以省略 //写||p!=NULL的主要原因是如果所有结点都是右孩子结点,那么可能存在的问题的是可能不满足第二次循环的条件了 stack[++top] = p; p=p->lchild; */ while(top!=-1||p!=NULL){ //这里加上||p!=null的原因是有可能p永远都是右孩子,那么在执行第一次循环就结束了,所以要加上 while(p!= NULL){//如果左孩子不为空,那么左孩子就一直进栈 stack[++top] = p; p=p->lchild; } //没有左孩子了就出栈,并让指针指向该结点的右孩子 printf("%d",stack[top]->data); p = stack[top--]->rchild; printf("%d",p->data); } }}int main(){ printf("程序开始\n"); BTNode * p; p = createTree(); int width = getWidth2(p); printf("%d",width); return 0;}
阅读全文
0 0
- 二叉树的几个基本算法
- 二叉树的几个基本性质
- 二叉树的基本算法
- 二叉树的基本算法
- 二叉树的几个相关算法
- 几个基本的算法
- 二叉树基本算法
- 二叉树基本算法
- 二叉查找树的定义以及几个基本操作
- 数据结构复习——二叉树的几个基本操作
- 二叉树树的基本算法
- 二叉树的基本遍历算法
- 二叉树的基本算法实现
- 平衡二叉查找树的基本算法
- 二叉树的基本遍历算法
- 二叉树各种基本运算的算法
- 二叉树的几个基础遍历算法代码
- 线索二叉树 基本算法
- Openlayers 3加载XYZ示例
- HBase结合MapReduce批量导入
- 数据结构 栈、队列
- java中抽象类和接口的一般实现和特殊实现(匿名类)
- 永洪科技千人用户大会上 AI与Reporting产品正式发布
- 二叉树的几个基本算法
- 直播CDN架构随想
- studio禁用插件
- 前端工程师的调试技能
- 如何通过 JMeter 测试 Predix 应用内部连通性
- LeetCode——Min Stack
- 交易型系统设计的一些原则
- Ubuntu更新软件源
- 这是一个转型AI的励志故事,从非科班到拿下竞赛一等奖