二叉树的最近公共祖先:

1:概念:就是两个节点在这棵树上深度最大的公共的祖先节点。

换句话说,就是两个点在这棵树上距离最近的公共祖先节点。

2:因为是基础课,所以tarjan和倍增lca就留到中级课再写

有兴趣的可以看这个算法详解之最近公共祖先(LCA) - hulean - 博客园 (cnblogs.com)

3:简单的两种方法

a:用数组存相比

b:先到同一深度在往上找

代码题目看后面

二叉搜索树:

当然这个还是基础的,后续再更

1:若它的左子树不为空,则左子树上所有结点的值都小于根结点的值。
2:若它的右子树不为空,则右子树上所有结点的值都大于根结点的值。

3:由于二叉搜索树中,每个结点左子树上所有结点的值都小于该结点的值,右子树上所有结点的值都大于该结点的值,因此对二叉搜索树进行中序遍历后,得到的是升序序列。

同时利用这个性质已知中序,后序,可以建立这个树

因为对于二叉搜索树左小右大的原则,其中序遍历即为树中的元素的升序排列;而后序遍历是按先左子右子再根节点的顺序输出;

因此 对于二叉搜索树而言

如果按照其后序遍历的颠倒后的顺序插入元素,就可以还原整棵树!

原因是在元素x被插入以前,x的父节点已经插入在树中(后序遍历的颠倒后的顺序),因此x一定会插入到原来的树中的位置上。

代码题目看后面

注意:不适合下标太大的;

前序,中序,后序 问题:

1:序转换问题

a:可以构建二叉搜索树(只适合已知中序,后序求前序)

b:递归处理,先找到根节点在分成两部分继续找根

递归处理可解决这两种,其中输出则是按前序,后序遍历的位置输出;

2:知道前序,后序,求中序的可能

我们首先可以明确的是,在一棵树上若有一个结点是只有一个子结点的那么这个子结点在左在右不影响先序后序的遍历顺序,那么总树数就要乘以2(乘法原理,这个子结点有两种选择,一种成为左子树,一种成为右子树),为了找到只有一个子结点的结点数,我们继续。。

我们可以得到一个规律,在先序遍历中某一元素A的后继元素B,如果在后序遍历中A的前驱元素是B,那么A只有一个子树

1:遍历一般二叉树

给你一棵n个节点的二叉树, 节点编号为1..n,要你求出这棵二叉树的先序、中序和后序遍历。

树的形式用以下方式给出:

  • 输入第一行给出一个数n,表示节点数;
  • 根节点编号为1;
  • 后面n行,每行有两个数,第一个数为第i个节点的左儿子编号,第二个数为第i个节点的右儿子编号,如果编号为0表示没有这个子节点;
  • 输入保证是一棵二叉树。

输入格式

见题面。

输出格式

输出三行,每行n个数代表一种遍历。 第一行为先序遍历,第二行为中序遍历,第三行为后序遍历。

#include <bits/stdc++.h>

using namespace std;
struct Tree{
int vaule;
Tree *l,*r,*fa;
}a[1025];
void front(Tree *x)
{
printf("%d ",x->vaule);
if(x->l)
front(x->l);
if(x->r)
front(x->r);
}
void mid(Tree *x)
{
if(x->l)
mid(x->l);
printf("%d ",x->vaule);
if(x->r)
mid(x->r);
}
void up(Tree *x)
{
if(x->l)
up(x->l);
if(x->r)
up(x->r);
printf("%d ",x->vaule);
}
int main()
{
int n;
scanf("%d",&n);
for(int i = 1;i <= n;i ++ )
{
int x,y;
scanf("%d %d",&x,&y);
a[i].vaule = i;
if(x)
a[i].l = &a[x];
if(y)
a[i].r = &a[y];
}
front(&a[1]);
printf("\n");
mid(&a[1]);
printf("\n");
up(&a[1]);
printf("\n");
}

2:二叉树的最近公共祖先

给你一棵n个节点的二叉树, 节点编号为1..n。

树的形式用以下方式给出:

  • 输入第一行给出一个数n,表示节点数;
  • 根节点编号为1;
  • 后面n行,每行有两个数,第一个数为第i个节点的左儿子编号,第二个数为第i个节点的右儿子编号,如果编号为0表示没有这个子节点;
  • 输入保证是一棵二叉树。

接下来一个给出两个节点编号u,v你需要求出这两个节点的最近公共祖先。

最近公共祖先(LCA)问题是指:对于两个节点u,v,找到一个深度最大的x是u,v的祖先。

输入格式

第一行一个整数n。 接下来n行,每行两个整数,表示第i个节点的儿子信息。 接下来一行两个整数u,v。

输出格式

输出一个数,代表u,v的最近公共祖先x。

1:解法一:数组

#include <bits/stdc++.h>

using namespace std;
struct Tree{
int vaule;
Tree *l,*r,*fa;
}a[1025];
int res[1025],pos[1025];
int main()
{
int n;
scanf("%d",&n);
for(int i = 1;i <= n;i ++ )
{
int x,y;
scanf("%d %d",&x,&y);
a[i].vaule = i;
if(x)
a[i].l = &a[x],a[x].fa = &a[i];
if(y)
a[i].r = &a[y],a[y].fa = &a[i];
}
int x,y,cnt = 0,cnt1 = 0;
scanf("%d %d",&x,&y);
while(x != 1)
{
res[++ cnt] = x;
// cout << x << ' ';
x = a[x].fa->vaule;
}
// cout << '\n';
res[++cnt] = 1;
while(y != 1)
{
pos[++ cnt1] = y;
y = a[y].fa->vaule;
}
pos[++cnt1] = 1;
int ans = 0;
for(int i = cnt ,j = cnt1;i||j;i--,j--)
{
if(res[i] == pos[j])
ans = res[i];
else
break;
}
printf("%d\n",ans);
}
 

2:解法而:深度

#include <bits/stdc++.h>

using namespace std;
struct Tree{
int vaule;
Tree *l,*r,*fa;
}a[1025];
void front(Tree *x)
{
printf("%d ",x->vaule);
if(x->l)
front(x->l);
if(x->r)
front(x->r);
}
void mid(Tree *x)
{
if(x->l)
mid(x->l);
printf("%d ",x->vaule);
if(x->r)
mid(x->r);
}
void up(Tree *x)
{
if(x->l)
up(x->l);
if(x->r)
up(x->r);
printf("%d ",x->vaule);
}
int main()
{
int n;
scanf("%d",&n);
for(int i = 1;i <= n;i ++ )
{
int x,y;
scanf("%d %d",&x,&y);
a[i].vaule = i;
if(x)
a[i].l = &a[x];
if(y)
a[i].r = &a[y];
}
front(&a[1]);
printf("\n");
mid(&a[1]);
printf("\n");
up(&a[1]);
printf("\n");
}

3:求先序排列

题目描述

给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示)。

输入格式

共两行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。

输出格式

共一行一个字符串,表示一棵二叉树的先序。

1:解法一:二叉搜索树

#include <bits/stdc++.h>

using namespace std;
int n;
char mid[1025],up[1025];
int p[1025];
char q[1025];
struct Tree{
int vaule;
Tree *l,*r,*fa;
}*head;
Tree* buildtree(Tree *root,int num)
{
Tree *z = (Tree *)malloc(sizeof(Tree));
Tree *y = NULL;
Tree *x = root;
z->vaule = num;
while(x != NULL)
{
y = x;
if(num < x->vaule)
x = x->l;
else
x = x->r;
}
z->fa = y;
if(y == NULL)
root = z;
else if(num < y->vaule)
y->l = z;
else
y->r = z;
return root;
}
void prve(Tree * t)
{
if(t == NULL)
return ;
printf("%c",q[t->vaule]);
prve(t->l);
prve(t->r);
}
int main()
{
head = NULL;
//cin>>mid>>pre;
scanf("%s %s",mid,up);
for(int i=0;mid[i]!='\0';i++)//建立字母与标号的双向联系
{
p[mid[i]]=i;
q[i]=mid[i];
}
for(int i = strlen(up) - 1;i >= 0; i --)
{
head = buildtree(head,p[up[i]]);
}
prve(head);
}

2:解法二:递归

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
void beford(string in,string after){
if (in.size()>0){
char ch=after[after.size()-1];
cout<<ch;//找根输出
int k=in.find(ch);
beford(in.substr(0,k),after.substr(0,k));
beford(in.substr(k+1),after.substr(k,in.size()-k-1));//递归左右子树;
}
}
int main(){
string inord,aftord;
cin>>inord;cin>>aftord;//读入
beford(inord,aftord);cout<<endl;
return 0;
}

4.遍历问题

题目描述

我们都很熟悉二叉树的前序、中序、后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中序遍历序列你也能求出它的前序遍历。然而给定一棵二叉树的前序和后序遍历,你却不能确定其中序遍历序列,考虑如下图中的几棵二叉树:

所有这些二叉树都有着相同的前序遍历和后序遍历,但中序遍历却不相同。

输入格式

输A数据共两行,第一行表示该二叉树的前序遍历结果s1,第二行表示该二叉树的后序遍历结果s2。

输出格式

输出可能的中序遍历序列的总数,结果不超过长整型数

#include <bits/stdc++.h>

using namespace std;
char pre[100001],up[100001];
int main()
{
scanf("%s %s",pre,up);
int ans = 1;
for(int i = 0;i <= strlen(pre) - 2; i ++ )
{
for(int j = 0; j <= strlen(pre) - 1; j ++ )
if(pre[i] == up[j] && pre[i + 1] == up[j - 1])
ans*=2;
}
printf("%d\n",ans);
}

daimayuan第二课(1.二叉树的遍历,2.二叉树的最近公共祖先,3.二叉搜索树)的更多相关文章

  1. PAT 1043 Is It a Binary Search Tree (25分) 由前序遍历得到二叉搜索树的后序遍历

    题目 A Binary Search Tree (BST) is recursively defined as a binary tree which has the following proper ...

  2. 《剑指offer》第三十三题(二叉搜索树的后序遍历序列)

    // 面试题33:二叉搜索树的后序遍历序列 // 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果. // 如果是则返回true,否则返回false.假设输入的数组的任意两个数字都 ...

  3. PAT树_层序遍历叶节点、中序建树后序输出、AVL树的根、二叉树路径存在性判定、奇妙的完全二叉搜索树、最小堆路径、文件路由

    03-树1. List Leaves (25) Given a tree, you are supposed to list all the leaves in the order of top do ...

  4. 二叉树系列 - 二叉搜索树 - [LeetCode] 中序遍历中利用 pre节点避免额外空间。题:Recover Binary Search Tree,Validate Binary Search Tree

    二叉搜索树是常用的概念,它的定义如下: The left subtree of a node contains only nodes with keys less than the node's ke ...

  5. [LeetCode]105. 从前序与中序遍历序列构造二叉树(递归)、108. 将有序数组转换为二叉搜索树(递归、二分)

    题目 05. 从前序与中序遍历序列构造二叉树 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 题解 使用HashMap记录当前子树根节点在中序遍历中的位置,方便每次 ...

  6. 二叉搜索树 & 二叉树 & 遍历方法

    二叉搜索树 & 二叉树 & 遍历方法 二叉搜索树 BST / binary search tree https://en.wikipedia.org/wiki/Binary_searc ...

  7. 剑指 Offer 33. 二叉搜索树的后序遍历序列 + 根据二叉树的后序遍历序列判断对应的二叉树是否存在

    剑指 Offer 33. 二叉搜索树的后序遍历序列 Offer_33 题目详情 题解分析 本题需要注意的是,这是基于一颗二叉排序树的题目,根据排序二叉树的定义,中序遍历序列就是数据从小到大的排序序列. ...

  8. C++版 - 剑指offer 面试题63:二叉搜索树的第k个结点(二叉树中序遍历的应用) 题解

    面试题 63:二叉搜索树的第k个结点 题目:给定一颗二叉搜索树,请找出其中的第k大的结点.例如, 5 / \ 3 7 /\ /\ 2 4 6 8 (见下面的图1) 中,按结点数值大小顺序第三个结点的值 ...

  9. 【遍历二叉树】07恢复二叉搜索树【Recover Binary Search Tree】

    开一个指针数组,中序遍历这个二叉搜索树,将节点的指针依次保存在数组里, 然后寻找两处逆序的位置, 中序便利里BST得到的是升序序列 ++++++++++++++++++++++++++++++++++ ...

  10. 剑指OFFER之从二叉搜索树的后序遍历序列(九度OJ1367)

    题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 输入: 每个测试案例包括2行: 第一行为1个整数 ...

随机推荐

  1. EhLib 9安装

    EhLib 9安装 安装EhLib: 在Installer文件夹里找到EhLibInstaller.exe,右键以管理员权限运行EhLibInstaller.exe. 按照提示一路安装下来,顺利完成. ...

  2. 分布式锁 -- redis

    原理 redis设置一个key和value,如果存在则获取锁失败,不存在则获取锁成功处理业务,业务处理完成后删除这条数据,可以带个失效时间. 代码 public void handleInvoice( ...

  3. Scp 免密拷贝

    为了图方便 想在更新主机服务的同时把应用同步到备机, 需做一下ssh 的公钥设置 详细见该链接 scp免密传输文件 - lucas-xie - 博客园 (cnblogs.com)

  4. JS中call、apply、bind

    call就是挨个传值,apply传一个数组,bind也是挨个传值 call() 和 apply() 会执行这个函数bind并不会而是将绑定好的this重新返回一个新函数

  5. js 浮点数加、减、乘、除。

    1.浮点数加法运算 function numAdd(arg1, arg2) { var r1, r2, m; try { r1 = arg1.toString().split("." ...

  6. python retry装饰器

    from functools import wraps import time # def retry(retry_time, retry_on_result, time_wait): # def t ...

  7. 后台运行python服务 起停脚本

    启动脚本 start.sh #!/bin/bash nohup <command> > /dev/null 2>&1 & echo $! > comman ...

  8. ajax thisisunsafe

    ajax 从chrome发出,对方公钥证书不是符合要求CA签发的,则会ssl握手失败,也没有机会强制信任 比如:http代理服务器(三)fiddler[重点] 当然应该可以从ajax指定信任一切服务端 ...

  9. ES可视化平台kibana安装和使用

    一.kibana介绍 Kibana是一个针对Elasticsearch的开源分析及可视化平台,用来搜索.查看交互存储在Elasticsearch索引中的数据. 二.kibana安装 1.解压 tar ...

  10. p标签设置行数,超出部分用省略号隐藏

    p { overflow: hidden; text-overflow: ellipsis; -webkit-line-clamp: 2; word-wrap: break-word; display ...