考研 ing
努力努力再努力
**

第五章 树

1.基础知识

线索二叉树
typedef struct ThreadNode{ElemType data;struct ThreadNode *lchild,*rchild;int ltag,rtag;
}ThreadNode,*ThreadTree;中序线索二叉树构造(不带头结点)
void InThread(ThreadTree &p,ThreadTree &pre){if(p!=NULL){InThread(p->lchild,pre);if(p->lchild==NULL)p->lchild=pre,p->ltag=1;if(pre!=NULL&&pre->rchild==NULL)pre->rchild=p,pre->rtag=1;pre=p;InThread(p->rchild,pre);}
}
void CreateInThread(ThreadTree T){ThreadTree pre=NULL;if(T!=NULL){InThread(T,pre);pre->rchild=NULL;pre->rtag=1;}
}中序遍历(3种)
1.递归
void Inorder(BiTree T){if(T!=NULL){Inorder(T->lchild);visit(T);Inorder(T->rchild);}
}
2.非递归:用栈
void Inorder(BiTree T){InitStack(S);    p=T;while(p||!StackEmpty(S)){if(p)Push(S,p), p=p->lchild;else{Pop(S,p), visit(p);p=p->rchild;}}
}
3.非递归:用线索链表
void Inorder(BiTree T){p=T;while(p!=NULL){while(p->ltag==0)  p=p->lchild;visit(p);while(p->rtag==1&&p->rchild!=NULL)p=p->rchild, visit(p);p=p->rchild;}
}

2.寻找二叉树两结点最近邻祖先

ElemType comancestor(SqTree T,int i,int j){if(T[i]!='#'&&T[j]!='#'){                       //两结点存在while(i!=j){if(i>j)  i=i/2;else j=j/2;}return T[i];}
}

3.后序遍历(非递归)

void postorder(BiTree T){p=T;InitStack(S);r=NULL;while(p||!IsEmpty(S)){if(p)Push(S,p), p=p->lchild;else{GetTop(S,p);if(p->rchild&&p->rchild!=r)p=p->rchild;else{Pop(S,p);visit(p->data);r=p;p=NULL;}}}
}

4.层次遍历的逆

//思想:先层次遍历入栈再输出即可得其逆
void InvertLevel(BiTree T){InitStack(S);InitQueue(Q);EnQueue(Q,T);while(!IsEmpty(Q)){DeQueue(Q,p);Push(S,p);if(p->lchild)    EnQueue(Q,p->lchild);if(p->rchild)    EnQueue(Q,p->rchild);    }while(!IsEmpty(S)){Pop(S,p);visit(p);}
}

5.二叉树的深度

1.非递归:利用层次遍历
int depth(BiTree T){if(!T)return 0;int front=-1,rear=-1;int last=0,level=0;BiTree Q[Maxsize];Q[++rear]=T;BiTree=p;while(front<rear){p=Q[++front];if(p->lchild) Q[++rear]=p->lchild;if(p->rchild)  Q[++rear]=p->rchild;if(front==last)level++,last=rear;}return level;
}
2.递归
int depth(BiTree T){if(!T)return 0;ldep=depth(T->lchild);rdep=depth(T->rchild);if(ldep>rdep)return ldep+1;elsereturn rdep+1;
}

6.知中序和先序遍历建立二叉链表

BiTree create(ElemType A[],ElemType B[],int l1,int h1,int l2,int h2){//开始时l1=l2=1,h1=h2=n//先序遍历第一个和最后一个结点下标为l1和h1//中序遍历第一个和最后一个结点下标为l2和h2root=(BiNode *)malloc(sizeof(BiNode));root->data=A[l1];for(i=l2;B[i]!=root->data;i++);llen=i-l2;rlen=h2-i;if(llen)create(A,B,l1+1,l1+llen,l2,l2+llen-1);elseroot->lchild=NULL;if(rlen)create(A,B,h1-rlen+1,h1,h2-rlen+1,h2);elseroot->rchild=NULL;return root;
}

7.判断一棵二叉树是否为完全二叉树

bool Iscomplete(BiTree T){if(!T)return 1;                        //空树是完全二叉树EnQueue(Q,T);while(!isEmpty(Q)){DeQueue(Q,p);if(p)EnQueue(Q,p->lchild),EnQueue(Q,p->rchild);else{while(!isEmpty(Q)){DeQueue(Q,p);if(p)  return 0;}} }return 1;
}

8.计算二叉树双分支结点个数

int DNode(BiTree T){if(!T)return 0;else if(T->rchild&&T->lchild)return DNode(T->lchild)+DNode(T->rchild)+1;else if(T->rchild||T->lchild)return DNode(T->lchild)+DNode(T->rchild);
}

9.交换左右子树

void swap(BiTree T){if(b){swap(T->lchild);swap(T->rchild);temp=T->lchild;T->lchild=T->rchild;T->rchild=temp;}
}

10.求前序遍历第k个结点值

int i=1;
ElemType PreNode(BiTree T,int k){if(!T)return '#';if(i==k)return T->data;i++;ch=PreNode(T-lchild,k);if(ch!='#')return ch;ch=PreNode(T->rchild,k);return ch;
}

11.删除值为x的结点和以该节点为根结点的树

//思想:找到值为x的结点,删除该节点左子树和右子树
删除操作
void DeleteX(BiTree &T){if(T){DeleteX(T->lchild);DeleteX(T->rchild);free(T);}
}
主函数
void Search(BiTree T,ElemType x){if(T){if(T->data==x){DeleteX(T);exit(0);}BiTree Q[];                      //层次遍历队列寻找xEnQueue(Q,T);while(!isEmpty(Q)){DeQueue(Q,p);if(p->lchild){if(p->lchild->data==x)DeleteX(p->lchild), p->lchild=NULL;elseEnQueue(Q,p->lchild);}if(p->rchild){if(p->rchild->data==x)DeleteX(p->rchild), p->rchild=NULL;elseEnQueue(Q,p->rchild);}    }
}

12.输出值为x的结点的所有祖先

typedef struct{BiTree T;int tag;             //tag=0,左子树已访问;tag=1,右子树已访问
}stack;
void shuchu(BiTree T,ElemType x){p=T;stack s[];top=0;while(p||top>0){while(p&&p->data!=x){s[++top].T=p;s[top].tag=0;p=p->lchild;}if(p->data==x){for(i=1;i<=top;i++)visit(s[i].T->data);exit(1);}while(top>0&&s[top].tag==1)top--;if(top>0){s[top].tag=1;p=s[top].T->rchild;}}
}

13.任意两结点最近邻公共祖先

思想:后序遍历栈中所剩元素皆为结点祖先,不失一般性,假设p在q的左边。即先遍历到p,然后遍历到q。
typedef struct{BiTree t;int tag;
}stack;
BiTree ancestor(BiTree root,BiTNode *p,BiTNode *q){stack s[],sl[];top=0,bt=root;while(top>0||bt){while(bt){s[++top].t=bt;s[top].tag=0;         //访问左孩子为0,访问右孩子为1bt=bt->lchild;}while(top>0&&s[top].tag==1){if(s[top].t==p){for(i=1;i<=top;i++)sl[i]=s[i];topl=top;}if(s[top].t==q)for(i=top;i>0;i--){for(j=topl;j>0;j--)if(s[i].t==sl[j].t)return s[i].t;}top--;}if(top>0){s[top].tag=1;bt=s[top].t->rchild;}}return NULL;
}

14.二叉树宽度

思想:层次遍历,标记层数,最后数每层结点个数。
typedef struct{BiTree data[maxsize];int level[maxsize];int front,rear;
}qu;
int BTwidth(BiTree b){BiTree p;int k,max,i,n;qu.front=qu.rear=-1;qu.rear++;qu.data[qu.rear]=b;qu.data[qu.rear]=1;while(qu.front<qu.rear){qu.front++;p=qu.data[qu.front];k=qu.level[qu.front];if(p->lchild){qu.rear++;qu.data[qu.rear]=p->lchild;qu.level[qu.rear]=k+1;}if(p->rchild){qu.rear++;qu.data[qu.rear]=p->rchild;qu.level[qu.rear]=k+1;}}max=0,i=0;k=1;while(i<=q.rear){n=0;while(i<=q.rear&&qu.level[i]==k)n++,i++;k=qu.level[i];if(n>max)   max=n;}return max;
}

15.满二叉树已知先序求后序

思想:一般二叉树只知先序和后序无法确定树。
但对于满二叉树,任一结点的左右子树包含结点数相等,故先序的第一个为后序的最后一个,先序的左右子树分别利用递归方法求得最终结果。
void pretopost(ElemType pre[],int l1,int h1,ElemType post[],int l2,int h2){//l1,h1,l2,h2分别为先序和后序得第一和最后一个结点int half;if(h1>=l1){post[h2]=pre[l1];half=(h1-l1)/2;pretopost(pre,l1+1,l1+half,post,l2,l2+half-1);pretopost(pre,l1+half+1,h1,post,l2+half,h2-1);}
}

16.将叶结点从左到右连接

思想:中序遍历
LinkList head,pre=NULL;            //定义全局变量,可以连续记忆
LinkList InOrder(BiTree bt){if(bt){InOrder(bt->lchild);if(!bt->lchild&&!bt->rchild){if(!pre){head=bt;pre=bt;}else{pre->rchild=bt;pre=bt;}}InOrder(bt->rchild);pre->rchild=NULL;}return head;
}

17.判断两棵树是否相似

int similar(BiTree t1,BiTree t2){int lefts,rights;if(t1==NULL&&t2==NULL)return 1;else if(t1==NULL||t2==NULL)return 0;else{lefts=similar(t1->lchild,t2->lchild);rights=similar(t1->rchild,t2->rchild);return lefts&&rights;}
}

18.中序线索二叉树查找结点在后序遍历中的前驱

BiThrTree Inpostpre(BiThrTree t,BiThrTree p){BiThrTree q;if(p->rtag==0)q=p->rchild;else if(q->ltag==0)q=p->lchild;else if(q->lchild==NULL)q=NULL;else{while(p->ltag==1&&p->lchild!=NULL)p=p->lchild;if(p->ltag==0)q=p->lchild;elseq=NULL;}return q;
}

19.带权路径长度之和

typedef struct BiTNode{int weight;struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;思路一:先序遍历到叶结点,wpl=权值*路径长度
int WPL(BiTree root){return wpl_preorder(root,0);
}
int wpl_preorder(BiTree bt,int deep){static int wpl=0; //定义静态变量存储wpl,程序执行前创建,执行期间一直存在if(bt->lchild==NULL&&bt->rchild==NULL)wpl+=deep*bt->weight;if(bt->lchild!=NULL)wpl_preorder(bt->lchild,deep+1);if(bt->rchild!=NULL)wpl_preorder(bt->rchild,deep+1);return wpl;
}思路二:层次遍历,记录层数,到达叶结点,累计wpl
#define maxsize 100
int wpl_levelorder(BiTree root){BiTree q[maxsize];int end1,end2;end1=end2=0;int wpl=0,deep=0;BiTree lastnode,newlastnode;lastnode=root,newlastnode=NULL;q[end2++]=root;while(end1!=end2){BiTree t=q[end1++];if(t->lchild==NULL&&t->rchild==NULL)wpl+=deep*t->weight;if(t->lchild!=NULL){q[end2++]=t->lchild;newlastnode=t->lchild;}if(t->rchild!=NULL){q[end2++]=t->rchild;newlastnode=t->rchild;}if(t=lastnode){lastnode=newlastnode;deep+=1;}}return wpl;
}

20.将二叉树转换为中缀表达式

void BtoE(BTree *root){BtoExp(root,1);
}
void BtoExp(BTree *root,int deep){if(root==NULL)return;else if(root->left==NULL&&root->right==NULL)printf("%s",root->date);else{if(deep>1)  printf("(");BtoExp(root->left,deep+1);printf("%s",root->data);BtoExp(root->right,deep+1);if(deep>1)   printf(")");}
}

树(2021.7.11晚)相关推荐

  1. 武林大会之国产数据库风云榜-2021年11月

    神秘能量篇: 话说在盘古开天之后,有一种神秘的能量出现于天地,后人称之为"数据",人们先后利用骨制品.绳结.纸张.算盘等工具尝试存储并使用这股神秘的力量,又在计算机发明之后,信息可 ...

  2. 微星 MSI GF63 i5-8300H+8G+128G+UHD630 基本完美黑苹果,把EFI分享给各位(2021.8.11 更新)

    2021.8.11 更新: EFI链接:https://github.com/n1celll/msi-gf63-oc-efi clover 升级成了 OC 引导,驱动了原生Intel卡 超帅的引导界面 ...

  3. 关于2021年11月28日PMI认证考试的报名通知

    尊敬的各位考生: 经PMI和中国国际人才交流基金会研究决定,中国大陆地区2021年全国第二期PMI认证考试于11月28日举办,相关事项通知如下. 一.时间安排和举办地区 (一)考试时间:2021年11 ...

  4. 2021年11月_IEEE Transactions on Geoscience and Remote Sensing_科技前言热点调查表

    IEEE Transactions on Geoscience and Remote Sensing文献跟踪 2021年11月 •  59卷 • 第11期 可视化分析: 文献名/代码开源/推荐 研究部 ...

  5. 从2021京东11.11,感受中国消费大变局

    2021双十一结束了.与往年相比,今年几大电商平台都采取了拉长战线模式,也就是从10月20日到11月11日主要分成了预售和预热两大阶段,京东与天猫更是分为了第一波和第二波的预售与预热,再加上双十一当日 ...

  6. 考研进度记录表(2021.6-2021.11)

    日期 剩余天数 101 英语 数学 专业课 5.29 211 <高等数学>第一章:函数与极限 第一节:映射与函数 第二节:数列的极限 第三节:函数的极限 第四节:无穷小与无穷大 第五节:极 ...

  7. 新鲜出炉 | 临床基因组学数据分析实战将于2021年11月12-14开课!!!

    福利公告:为了响应学员的学习需求,经过易生信培训团队的讨论筹备,现安排<临床基因组学数据分析实战>于2021年11月12-14 线上/线下课程 (线上课是通过腾讯会议实时直播线下课,实时互 ...

  8. 2021.4.11 字节跳动实习笔试题---情报解密

    2021.4.11 字节跳动实习笔试题-情报解密 题目内容 题目内容: 给你一个字符串,该字符串中有数字,字母(字母只有大写字母)以及一些其他的字符(例如:%,.等),如果首字母为字母或者数字的话,就 ...

  9. Drupal7 将到2021年11月结束支持,请注意升级

    Drupal Association 宣布, 2011年1月释出的 Drupal 7 将到2021年11月结束支持,这意味着 Drupal 安全团队将不会继续为 Drupal 7 核心或模块.主题等提 ...

最新文章

  1. ESPNet: 自动驾驶领域轻量级分割模型
  2. 如何知道iframe文件下载download完成
  3. dbus 和 policykit 实例篇(python)
  4. ubuntu路由器联网_路由器及其协议简介| 联网
  5. ————————————————素数的快速判断方法————————————————————...
  6. 一个简单的MDX案例及说明 (转载)
  7. 屏幕取色器设计思路及源码
  8. 基于51单片机的智能温控风扇设计
  9. MA8601 无需更改电路直接pin√pin替代FE8.1s方案
  10. 程序员常用英文单词汇总
  11. python自动生成word报表之使用win32com插入自带可编辑的图表
  12. 打印机服务器ip修改,打印机服务器ip设置
  13. mes系统的主要功能是什么?看完这篇你就懂了
  14. 《O2P卸甲笔记》附录:Oracle XE快速安装
  15. 第十三周 任务二
  16. html中左括号怎么写,HTML基础 特殊符号 左右尖括号 与 货币 乘 除
  17. 免费下载电子书!618大促背后前端代码如何智能生成?
  18. maven 打包排除指定文件
  19. 野火STM32F407-霸天虎DSP库移植
  20. Mockito 也能 Mock final 类和 final 方法了

热门文章

  1. [原创]简易文本编辑器( 无界面)
  2. Innovus基础命令:createPlaceBlockage
  3. criterial查询
  4. python使用pika订阅rabbitmq消息链接被重置问题
  5. 贝叶斯 定理_贝叶斯定理:批判性思维框架
  6. 数据库备份服务器性能指标,服务器处置性能估算
  7. 【原创】关于Golang和Rust对比及语言的选择思考
  8. css 网页自适应 @media screen详解
  9. Navicat 连接阿里云上的数据库
  10. Xftp卸载修复报错1628:完成基于脚本的安装失败