DS森林叶子编码/森林转二叉树 【数据结构】

DS森林叶子编码

题目描述

给定一组森林,编写程序生成对应的二叉树,输出这颗二叉树叶结点对应的二进制编码.规定二叉树的左边由0表示,二叉树的右边由1表示。

输入

N B 表示N个树,每结点最多B个分支

第2行至第N+1行,每个树的先序遍历

输出

每行表示一个叶结点对应的二进制编码.

输入样例1

3 3\n

A B 0 0 0 C 0 0 0 D 0 0 0\n

E F 0 0 0 0 0\n

G H 0 0 0 I J 0 0 0 0 0 0\n

输出样例1

0 1 1\n

1 0\n

1 1 0 1 0\n

森林转二叉树

注意点:不是根节点的第一个子节点是左孩子,而是根节点的第一个非空 子节点是左孩子,同样的,一个结点的下一个非空 兄弟节点是他的右节点!!!!!
另外树的问题一定一定不要忽略一些空节点的赋值,一个非空节点的结构体中必要节点都一定要保证赋值到,不然会报错

另外,其实建了树后不用再特意转化为二叉树,因为我下面这种创建方法直接是一个有两个指针的结构体,可以直接当成二叉树来继续

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
struct tree
{
    char value;
    tree* left;
    tree* brother;
};

//创建树
tree* setTree(char c[],int b,int& index,int j)
{
    if(index>=j||c[index]=='0')
    {
        index++;
        return NULL;
    }
    tree* t=new tree;
    t->value=c[index];
    index++;
    if(b==1) t->brother=NULL;
    bool flag=0;
    tree* tr=NULL;
    tree* trr=NULL;
    for(int i=0;i<b;i++)
    {
        //这里可以防止重复setTree,直接用变量记录
        trr=setTree(c,b,index,j);
        
        //第一个非空子节点作为左孩子
        if(!flag&&trr!=NULL) 
        {
            t->left=trr;
            flag=1;
            tr=t->left;
            continue;
        }
        
        //这里就是要考虑一个节点下一个兄弟节点是空的情况
        if(tr==NULL||trr==NULL) 
        {
            if(tr==NULL&&trr!=NULL) tr=trr;
            else if(tr==NULL&&trr==NULL) tr=trr;
            else tr=tr;
        }
        
        else 
        {
            tr->brother=trr;
            tr=tr->brother;
        }
        
        //注意要给每个根节点最后一个子节点的兄弟节点赋值空指针!!!
        if(tr&&i==b-1) tr->brother=NULL;
    }
    if(flag==0) t->left=NULL;
    return t;
}
string s[105];
int flag=0;

//查找叶子节点
void findLeaf(string path,tree* t)
{
    if(t==NULL) return ;
    else if(t!=NULL&&t->left==NULL&&t->brother==NULL)
    {
        s[flag]=path;
        flag++;
        return ;
    }
    findLeaf(path+"0",t->left);
    findLeaf(path+"1",t->brother);
}

int main()
{
    int n,b;
    cin>>n>>b;
    getchar();
    tree* trees[105];
    for(int i=0;i<n;i++)
    {
        char c[105];
        char ch;
        int j=0,index=0;
        while((ch=getchar())!='\n')
        {
            c[j]=ch;
            j++;
            if(getchar()=='\n') break;
        }
        
        //先分别创建树,存进数组中
        tree* t=new tree;
        t=setTree(c,b,index,j);
        trees[i]=t;
    }
    
    //给每个树的根节点的兄弟节点赋值
    for(int i=0;i<n-1;i++) trees[i]->brother=trees[i+1];
    
    //最后一个树的根节点的兄弟节点赋值空指针
    trees[n-1]->brother=NULL;
    findLeaf("",trees[0]);
    for(int i=0;i<flag;i++)
    {
        for(int j=0;j<s[i].size();j++)
        {
            (j==0)?cout<<s[i][j]:cout<<" "<<s[i][j];
        }
        cout<<endl;
    }
    return 0;
}
相关推荐
绿算技术20 分钟前
Solidigm联合绿算技术共同发布《面向 SOHO AI 推理的存储扩展方案》技术白皮书
人工智能·科技·算法·架构·spark
小刘在重生~42 分钟前
Java 集合|Collection、List、ArrayList、LinkedList、泛型、Collections 工具类
java·数据结构·list
EDPJ1 小时前
(2026|IPI|我的论文投稿中,PSP 超轻量采样算法,轻量化架构探索/早融合+头压缩)LUMIN:面向工业异常检测的轻量级通用制造检测网络
算法·计算机视觉·架构·异常检测·采样算法
我不会起名字3221 小时前
一天一道算法题(29):单调栈
java·数据结构·python·算法·leetcode·golang·单调栈
苦瓜小生1 小时前
【前端】【力扣与手撕】十天带你刷完前端算法与手撕,全是最简单好记的最优解法!day4
前端·数据结构·算法·leetcode·面试
不会就选b2 小时前
算法日常・每日刷题--<贪心>5
算法
刘广睿2 小时前
素材去重为什么难?文件指纹、感知哈希与相似度判定的设计笔记
算法·哈希算法·产品设计·素材管理
少司府2 小时前
C++进阶:智能指针
开发语言·数据结构·c++·b树·算法·c·智能指针
鹿角片ljp3 小时前
LeetCode 22:括号生成|回溯dfs、剪枝与 char[] 覆盖代替撤销
算法·深度优先
sylviiiiiia3 小时前
leetcode hot100
python·算法·leetcode