每日总结之二叉树2.2

目录

 算法学习

 1.新二叉树

2.二叉树深度(高度)

刷题网站 

1.全排列

2.找规律

3.萝卜的冒泡排序


 算法学习

 1.新二叉树

P1305 新二叉树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1305


1.dfs递归:前序:根左右

2.输入问题:题干:特别地,数据保证第一行读入的节点必为根节点。所以,根结点begin单独输入,后续节点for中 i=1从1开始输入;

3.注意:getchar();洛谷c编译器对struct的读入bug;

#include<stdio.h>
struct node
{
    char l,r;

} tree[100];
void dfs(char ch)                         //前序遍历
{
    printf("%c",ch);                      //根
    if(tree[ch].l!='*')dfs(tree[ch].l);   //左
    if(tree[ch].r!='*')dfs(tree[ch].r);   //右
}
int main()
{
    int n;
    char a,l,r,begin;
    scanf("%d",&n);
    getchar();                          //注意吸收回车
    scanf(" %c%c%c",&begin,&l,&r);      //洛谷c编译器问题,加个空格‘ ’对应结构体
    getchar();
    tree[begin].l=l;
    tree[begin].r=r;
    for(int i=1; i<n; i++)
    {
        scanf(" %c%c%c",&a,&l,&r);
        tree[a].l=l;
        tree[a].r=r;
        getchar();
    }
    dfs(begin);
    return 0;
}

2.二叉树深度(高度)P4913 【深基16.例3】二叉树深度 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P4913


1.结构体设置:孩子表示法,读入left,right(左右孩子)

2.搜索dfs(不撞南墙不回头):参量设置pos,deep,分别为该结点pos,树的深度deep

3.终止条件:找到叶子(0,0),叶子无孩子不再向下延伸,同时找深度max

#include<stdio.h>
struct node
{
    int l;
    int r;
}tree[1000005];
int ans=-1;                           //比较深度,初始值设小点

int max(int a,int b)
{
    return a>b?a:b;
}

void dfs(int pos,int deep)
{
    if(tree[pos].l==0&&tree[pos].r==0)    //==叶节点时,结束深搜
    {
        ans=max(ans,deep);               //每层到达叶节点深度不同,找max
        return ;
    }
    dfs(tree[pos].l,deep+1);             //递归,搜索下一层left
    dfs(tree[pos].r,deep+1);             //递归,搜索下一层right
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d %d",&tree[i].l,&tree[i].r);
    }
    dfs(1,1);                           //第一层开始搜
    printf("%d",ans);
}

刷题网站 

1.全排列

问题 L: 全排列(JSU-ZJJ)(❤❤❤❤) - OJ (jsuacm.cn)http://jsuacm.cn/problem.php?cid=1687&pid=11

1.思路: 可以用swap模拟搜索过程;

2.for循环设置:与同一字符数组里的其他字符交换

3.注意:利用字符输入字符数组时,空格也被当作字符输入,需要特判if(c!=' ')   s[m++]=c        

#include<stdio.h>
char s[6];
int n;
void dfs(int step)
{
    int i;
   if(step==n-1)
   {

       for(i=0;i<n;i++)
       {
           printf("%c",s[i]);
       }
       printf("\n");
       return ;
   }
   else
   {
       for(i=step;i<n;i++)
       {
               char x;               //注意中间变量类型
               x=s[step];
               s[step]=s[i];
               s[i]=x;               //交换
               
               dfs(step+1);
               
               x=s[step];           //回溯还原
               s[step]=s[i];
               s[i]=x;
       }
   }
}

int main()
{
    int k;
    while(~scanf("%d",&k))                   //多组输入
    for(int i=0;i<k;i++)
    {
        scanf("%d\n",&n);
        int m=0;
        for(int i=0;i<=n*2-1;i++)
        {
            char c;
            c=getchar();
            if(c!=' ')
               s[m++]=c;
        }
        s[m]='\0';
        dfs(0);
        printf("\n");
    }
}

2.找规律

问题 G: 奇怪的棋盘 - OJ (jsuacm.cn)http://jsuacm.cn/problem.php?cid=1687&pid=6 1.关键:找规律,通项公式

               此类题注意数据类型

#include<stdio.h>
int main()
{
    long long int a[55],i;
    a[1]=1;a[2]=2;
    for(i=3;i<51;i++)
        a[i]=a[i-1]+a[i-2];
    int n;
    while(~scanf("%d",&n))
    {
        printf("%lld\n",a[n]);
    }
}

3.萝卜的冒泡排序

问题 C: 萝卜的冒泡排序 - OJ (jsuacm.cn)http://jsuacm.cn/problem.php?cid=1686&pid=2

1.关键点:冒泡排序只能统计不同元素的交换个数,相同元素交换个数找规律;

2.注意:112223,每找到一次相同元素时就加上相应个数,不要把全部相同个数找完,1相同个数为2,2相同个数为3;

#include<stdio.h>
int main()
{
   int n,i,j,a[150];
   int ans=0;
   scanf("%d",&n);
   for(int i=0;i<n;i++)
   {
       scanf("%d",&a[i]);
   }
   for(i=0;i<n-1;i++)
    for(j=0;j<n-1-i;j++)
   {
       if(a[j]>a[j+1])
       {
           int t=a[j];
           a[j]=a[j+1];
           a[j+1]=t;
           ans++;
       }
   }
   int k=1;
    for(int i=0; i<n-1; i++)
    {
        if(a[i]==a[i+1])
        {
            k++;         //相邻元素相同,一
            ans+=k-1;   //加上相同元素之间交换的次数
        }
        else
            k=1;       //相邻元素不同,重新计数
    }
    printf("%d\n",ans);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值