北京化工大学数据结构2022/10/27作业 题解

news2024/10/7 12:18:04

目录

问题 A: 二叉树的性质

问题 B: 二叉树的节点

 问题 C: 满二叉树

 问题 D: 完全二叉树的节点序号

-----------------------------------分割线------------------------------------------

问题 E: 二叉树的深度

问题 F: 数据结构作业04 -- 二叉树的输入

递归版

迭代版

问题 G: 给定前序遍历序手动构造二叉树-附加代码模式


问题 A: 二叉树的性质

答案非常简单就是输出n-1

但怎么证的呢?

我们不妨先论证一下总的度数和节点数的关系(这里的度指的是子节点数)

最开始我们的树只有一个根节点,而每派生出一个“度”,也就派生出了一个子节点

所以在这之后派生出的总度数量是等于所以子节点数量的

在加上根节点,也就得到了下面式子

节点总数=总度数+1

而左边节点度数可以写成  度为0的节点+度为1的节点+度为2的节点

右边可以写成   2*度为2的节点+1*度为1的节点+1

上式即为 度为0的节点+度为1的节点+度为2的节点= 2*度为2的节点+1*度为1的节点+1

两边一合并

度为2的节点+1=度为0的节点

也就证出来了

代码如下

cpp

int n;
    cin>>n;
    cout<<n-1<<endl;

python

n = int(input())
print(n-1)

问题 B: 二叉树的节点

这个应该不难想

二叉树的深度取决于最深的节点

最少节点我们只要一条路走到黑或者之字形走,如下图

这样最少节点数就等于深度

(题外话)

也就是说基于二叉树实现的搜索树最坏情况会退化为链表,而在单链表中查找和指定删除都为n^{2}

边缘性能很差,这也就有了之后AVL,红黑树的故事 

最多也很简单

只需要每层都满节点就好了

也就是1+2+4....2^{n-1}

也就等于2^{n}-1

 cpp代码

    int n;
    cin>>n;
    cout<<n<<' '<<pow(2,n)-1;

python代码

h=int(input())
ma = pow(2,h)-1
print(h,ma)

 问题 C: 满二叉树

这道题同上了

满二叉树就是节点最多的时候

判断即可

cpp代码 

    int h,n;
    while(cin>>h>>n)
    {
        if (n==pow(2,h)-1) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }

python代码

while 1:
    h,n=map(int,input().split())
    if pow(2,h)-1 == n:
        print('YES')
    else:
        print('NO')

 问题 D: 完全二叉树的节点序号

我们用数组在存这种二叉堆结构有一个默认的方式,例如存线段树

左儿子等于父亲*2,右儿子等于父亲*2+1

例如存一棵value值如下图的7个节点的满二叉树

在数组中为

这样a[2]的儿子就是left:a[2*2],right:a[2*2+1]

也就是a[4]和a[5]

这题下标是从0开始,加个偏移量即可

代码如下

    int n;
    while(cin>>n){
        if(n==0) cout<<"-1 1 2\n";
        else cout<<(n-1)/2<<" "<<2*n+1<<" "<<2*n+2<<'\n';
    }

-----------------------------------分割线------------------------------------------

以下二叉树的前中后序遍历

思路详解见(2条消息) (数据结构)如何手搓一棵二叉树?_lxrrrrrrrr的博客-CSDN博客

我们只要实现一个简单的就好

问题 E: 二叉树的深度

先建树,在找深度

建树:他提供带虚节点前序遍历,前序遍历是 根左右

所以我们按照根左右的方式重构树即可,遇到虚节点时结束,代表当前点无节点

找深度时每个节点的dep=max(dep[left],dep[right])+1

从底层节点递归上来即可

代码如下

#include<bits/stdc++.h>
using namespace std;
int ind;
class node{
public:
    char data;
    int dep;
    node* left;
    node* right;
};
class bintree{
public:
    node* __root;
    void createtree(node* &T,string s);
    int updatadep(node *T);
};
void bintree::createtree(node* &T,string s){
    char data=s[ind];
    ind++;
    if(data=='#'){
        T=nullptr;
    }
    else{
        T=new node;
        T->data=data;
        createtree(T->left,s);
        createtree(T->right,s);
    }
}
int bintree::updatadep(node *T){
    int L,R;
    if(T!=NULL){
        L=updatadep(T->left);
        R=updatadep(T->right);     
        T->dep=L>R?L+1:R+1;
        return T->dep;
    }
    return 0;
}
signed main(){
    bintree tree;
    string str;
    int T;
    cin>>T;
    while(T--){
        cin>>str;
        bool fl=false;
        for(auto t:str){
            if(t!='#'){
                fl=true;
                break;
            }
        }
        if(!fl){cout<<"0\n";continue;}
        ind=0;
        tree.createtree(tree.__root,str);
        cout<<tree.updatadep(tree.__root)<<'\n';
    }
}

问题 F: 数据结构作业04 -- 二叉树的输入

建树前一道题已经建过了

这里主要说下中后序遍历

中序遍历我给出了两种方式

递归版和迭代版

递归版

中序遍历是按照 左--根--右 的方式遍历

递归版写起来特别简单

这样在回溯的时候就会按照中序遍历遍历这棵树

前后序遍历的递归版也就是调换一下顺序

迭代版

同样是从根节点开始,不断地沿着左子树向下走。不同的是,这里向下行进的过程中不能访问当前结点,只有等到当前结点的左子树完成访问时,才能轮到当前结点,因此想到引入一个栈来实现延迟缓冲的功能。走到最左侧的第一个没有左子树的叶子结点时,没有左子树也相当于已经完成了左子树的访问,于是随后便访问当前结点x,然后转入到x的右子树。

当x的右子树完成访问时,即标志着以x为根的子树访问完毕,随机访问x的父亲结点,然后访问x的父亲的右子结点。x的右兄弟结点访问完毕时,即标志着以x的父亲的根的子树访问完毕,随即访问x父亲的父亲,然后是x父亲的父亲的父亲...
 

后序遍历的详解去看(2条消息) (数据结构)如何手搓一棵二叉树?_lxrrrrrrrr的博客-CSDN博客

goAlongLeft函数的作用是对于每一个节点,一直向左走,这一条左链都压入栈

具体实现:对于每一个节点,先一直向左走,将他的所有左儿子都压入栈,之后每一个左儿子

按顺序出栈,遍历此节点,再遍历此节点的右节点,之后下一个左儿子出栈.....

 

代码如下:

#include<bits/stdc++.h>
using namespace std;
int ind;
class node{
public:
    char data;
    node* left;
    node* right;
};

class bintree{
public:
    node* __root;
    void createtree(node* &T,string s);
    void visit(node* T){if(T->data!='#') cout<<T->data;}
    void inorder(node* T);
    void postorder(node* T);
    void levelorder(node* T);

    void goalongleft(stack<node*> &S,node* now);
    void inorder_it(node* T);
};

void bintree::createtree(node* &T,string s){
    char data=s[ind];
    ind++;
    if(data=='#'){
        T=nullptr;
    }
    else{
        T=new node;
        T->data=data;
        createtree(T->left,s);
        createtree(T->right,s);
    }
}

void bintree::inorder(node* T){
    if(T!=nullptr){
        inorder(T->left);
        visit(T);
        inorder(T->right);
    }
}

void bintree::goalongleft(stack<node*> &S,node* now){
    node* curr=now;
    while(curr!=nullptr){
        S.push(curr);
        curr=curr->left;
    }
}

void bintree::inorder_it(node* T){
    stack<node*> S;
    node* curr=T;
    while(1){
        goalongleft(S,curr);
        if(S.empty()) break;
        curr=S.top();
        S.pop();
        visit(curr);
        curr=curr->right;
    }
}

void bintree::postorder(node* T){
    if(T!=nullptr){
        postorder(T->left);
        postorder(T->right);
        visit(T);
    }
}

void bintree::levelorder(node* T){
    queue<node*> q;
    q.push(this->__root);
    while(!q.empty()){
        node* top=q.front();
        q.pop();
        visit(top);
        if(top->left) q.push(top->left);
        if(top->right) q.push(top->right);
    }
}

signed main(){
    bintree tree;
    string str;
    while(cin>>str){
        bool fl=false;
        for(auto t:str){
            if(t!='#'){
                fl=true;
                break;
            }
        }
        if(!fl){cout<<"\n";continue;}
        ind=0;
        tree.createtree(tree.__root,str);
        tree.inorder(tree.__root);
        cout<<" ";
        // tree.inorder_it(tree.__root);
        // cout<<endl;
        tree.postorder(tree.__root);
        cout<<" ";
        tree.levelorder(tree.__root);
        cout<<'\n';
    }
}

问题 G: 给定前序遍历序手动构造二叉树-附加代码模式

随便编一个就行

using namespace std;
 
struct BiNode
{
    string data;
    BiNode *lchild, *rchild;
};
typedef BiNode *BiTree;
 
int InitBiTree(BiTree &T)
{
    T = NULL;
    return 0;
}
void ManuallyCreateTree(BiTree & T){
    T = new BiNode();
    T->data = "a";
 
    BiNode* n1 = new BiNode();
    n1->data = "b";
 
    BiNode* n2 = new BiNode();
    n2->data = "c";
    T->lchild = n1;
    T->rchild = n2;
 
    BiNode* p = new BiNode();
    p->data = "d";
 
    n1->lchild = p;
 
    BiNode* p1 = new BiNode();
    p1->data = "e";
 
    n1->rchild = NULL;
    n2->lchild = p1;
 
 
    BiNode* p2 = new BiNode();
    p2->data = "f";
 
    n2->rchild = p2;
} 

C语言毕竟不是面向过程的语言,用C写这种数据结构简直坐牢

毕竟高内聚低耦合的cpp写出来很养眼

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1330.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【第一阶段:java基础】第4章:java控制结构

本系列博客是韩顺平老师java基础课的课程笔记 韩顺平P103-P1551. 顺序2. 分支3. 循环4. 跳转5. 编程思想1. 顺序 程序从上至下逐行执行&#xff0c;中间没有任何判断和跳转 2. 分支 单分支if双分支if-else多分支if - else if … - else嵌套分支&#xff1a;建议嵌套最好不要…

【水果派不吃灰】Raspberry Pi树莓派Linux系统下替换国内apt软件更新源

目录1. 前言2. 备份原始配置文件3. 修改原始文件3.1 软件更新源3.2 系统更新源4. 更新4.1 sudo apt-get update 更新软件源列表4.1 sudo apt-get upgrade 更新软件版本(时间会久点)4.1 sudo apt-get dist-upgrade4.1 sudo rpi-update 内核版本&#xff08;尽量不更新&#xff0…

Web前端 | JavaScript(BOM编程和JSON)

✅作者简介&#xff1a;一位材料转码农的选手&#xff0c;希望一起努力&#xff0c;一起进步&#xff01; &#x1f4c3;个人主页&#xff1a;每天都要敲代码的个人主页 &#x1f525;系列专栏&#xff1a;Web前端 &#x1f4ac;推荐一款模拟面试、刷题神器&#xff0c;从基础到…

Matplotlib | 世界足球俱乐部排名可视化

文章目录&#x1f3f3;️‍&#x1f308; 1. 导入模块&#x1f3f3;️‍&#x1f308; 2. 示例数据&#x1f3f3;️‍&#x1f308; 3. 画布设置&#x1f3f3;️‍&#x1f308; 4. 画布区域主题分配&#x1f3f3;️‍&#x1f308; 5. 添加数据散点&#x1f3f3;️‍&#x1f…

Python学习六(进程)

1.简介 多进程在使用中是非常常见的&#xff0c;如果对多进程比较陌生&#xff0c;那可以换个说法&#xff0c;叫多任务。 那什么叫做多任务呢&#xff1f;顾名思义就是多个任务。比如我们使用电脑时&#xff0c;打开浏览器&#xff0c;是一个任务、打开视频&#xff0c;是一个…

MySQL是怎么保证数据不丢的

一.什么是两阶段提交 1.SQL语句&#xff08;update user set name‘李四’ where id3&#xff09;的执行流程是怎样的呢&#xff1f; 1.执行器先找引擎取 ID3这一行。ID 是主键&#xff0c;引擎直接用树搜索找到这一行。 2.如果 ID3 这一行所在的数据页本来就在内存中&#x…

【FLASH存储器系列二】非易失性存储器基本原理之EEPROM和FLASH

1 EEPROM 通过EPROM的原理分析我们知道&#xff0c;由于叠栅雪崩注入MOS晶体管&#xff08;SAMOS&#xff09;的结构特性&#xff08;浮栅周围是二氧化硅的绝缘层&#xff09;&#xff0c;而且由于早期工艺的原因&#xff0c;这个二氧化硅层比较厚&#xff0c;势垒比较高&#…

HTTP协议

哈喽,友友你好呀~今天要给大家分享的是关于HTTP协议的相关知识点,这部分的知识在web开发中还是很重要的一部分知识,耐点心看完,肯定会有收获滴~~ 目录 1.什么是HTTP 2.HTTP协议工作过程 3.什么是抓包工具 4.HTTP协议格式 4.1 HTTP请求(Request) 4.2 HTTP响应(Response) …

基于javaweb的停车库管理系统(java+jsp+jquery+servlet+mysql)

基于javaweb的停车库管理系统(javajspjqueryservletmysql) 运行环境 Java≥8、MySQL≥5.7、Tomcat≥8 开发工具 eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计&#xff0c;大作业&#xff0c;毕业设计&#xff0c;项目练习&#xff0c;学习演示等 功能说明 基…

补环境:vm2 transformer.js 源码分析

在补环境框架的文件夹里执行 vm2 文件能成功得到结果&#xff0c;但是将合并了环境和原 js 文件后的代码内容单独提取出来通过 vm2 调用却报错提示 SyntaxError: Use of internal vm2 state variable&#xff1a; 通过 transformer.js 源码&#xff0c;分析 VM2_INTERNAL_STATE…

【韩顺平老师讲MySQL】函数和多表查询

文章目录P33.数学函数P34.日期函数P37.加密函数P38.流程控制函数P39.查询增强P40.分页查询P41.分组查询P42.多子句查询P43.多表查询笛卡尔积(重难点)P44.多表查询P45.自连接P46.多行子查询P33.数学函数 # 绝对值 SELECT ABS(-12) FROM DUAL;# 十进制转为二进制 SELECT BIN(10) …

【offer拿到手软系列】面试小贴士

​ 学习好一门语言贵在坚持——初识JavaScript&#x1f3f9;&#x1f481;‍♂️&#xff01; 首先&#xff1a; 博主是&#x1f466;一个帅气的boy&#xff0c;你可以叫我山鱼君 &#x1f5b1; ⌨个人主页&#xff1a;山鱼菌的个人主页 &#x1f496;&#x1f496;如果对你有帮…

vmlogin多登防关联浏览器中配置Geolocation定位插件的使用教程

Geolocation 接口是一个用来获取设备地理位置的可编程的对象&#xff0c;它可以让Web内容访问到设备的地理位置&#xff0c;这将允许Web应用基于用户的地理位置提供定制的信息。说实话&#xff1a;其实Geolocation 就是用来获取到当前设备的经纬度&#xff08;位置&#xff09;…

Zookeeper ---- Zookeeper集群操作

Zookeeper ---- Zookeeper集群操作1. 集群操作1. 集群规划2. 选举机制&#xff08;面试重点&#xff09;3. ZK集群启动停止脚本2. 客户端命令操作1. 命令行语法2. znode节点数据信息3. 节点类型&#xff08;持久/短暂/有序号/无序号&#xff09;4. 监听器原理5. 节点删除与查看…

2022年NPDP新版教材知识集锦--【第三章节】(1)

【新产品开发概论】 产品创新是“风险与回报”的过程 随着新产品的累积成本增加&#xff0c;产品的不确定性降低。成功率在很大程度上取决于企业采用的新产品开发实践和流程的质量。 【决策基本框架】 ⚫识别问题或机会 ⚫收集信息(信息来源&#xff1a;内部、外部、内外部…

iOS开发之Undefined symbol:_OBJC_CLASS_$_****

更新了Xcode14.0.1以后&#xff0c;项目突然曝出了此问题Undefined symbol:_OBJC_CLASS_$_****&#xff0c;因此记录一下&#xff0c;解决此问题的步骤&#xff1a; 第一步&#xff1a;首先在Build Phases中找到 Compile Sources&#xff0c;查看是否有对应的***.m文件&#x…

查找算法【二叉查找树】 - 二叉查找树的插入

查找算法【二叉查找树】 - 二叉查找树的插入 因为二叉查找树的中序遍历存在有序性&#xff0c;所以首先要查找待插入关键字的插入位置&#xff0c;当查找不成功时&#xff0c;再将待插入关键字作为新的叶子节点成为最后一个查找节点的左孩子或右孩子。 【算法步骤】 ① 若二…

vim编辑器使用和vim一键配置

1.vim的三种模式 开始之前&#xff0c;先简单说&#xff0c;vim并不是只有这三种模式。总的来说vim大概有12种模式&#xff0c;不同的版本可能也有一些具体的区别。今天我们先介绍三种常用的模式。 先用一张图来大概介绍三种模式之间的转换 命令模式&#xff08;Normal mod…

强化学习算法实践(一)——策略梯度算法

文章目录Reference1. REINFORCE1.1 Basic1.2 Code2. Improvement Tips2.1 Assign Suitable Credit2.2 Add a Baseline2.3 Advantage Function3. Actor-Critic(A2C)3.1 Basic3.2 Code策略梯度是一种基于策略的算法&#xff0c;相比于DQN一类的基于价值的算法&#xff0c;它会直接…

C语言分支与循环--循环篇(图片,动画演示),彻底搞定C语言循环

前言 &#x1f47b;作者&#xff1a;龟龟不断向前 &#x1f47b;简介&#xff1a;宁愿做一只不停跑的慢乌龟&#xff0c;也不想当一只三分钟热度的兔子。 &#x1f47b;专栏&#xff1a;C初阶知识点 &#x1f47b;工具分享&#xff1a; 刷题&#xff1a; 牛客网 leetcode笔记软…