数据结构第三天 【二叉搜索树】

news2024/11/23 11:12:31

 这道题真是写的我想吐了,主要是函数太多,排错太难了,搞了两个小时,基本就是在排错,排了一个小时,后面自己心态也有点崩溃了,其实不是一道很难的题,但是是一个非常麻烦的题目,但是再麻烦的题目我现在已经做出来了,那就一起来盘一盘它吧,要不然过了几天就又白盘了,就忘的九霄云外去了。

1.如何建立一个搜索二叉树?

1.规定结构体,以及规定结构体指针(不然指针容易晕)

typedef struct TreeNode *Tree;
struct TreeNode{
    int v;
    Tree Left , Right;
    int flag;
};

有个问题:就是为啥这上面的这个结构体都没有定义。然而下面可以把它当做已经定义好的使用?

2. 初始化二叉树单个节点,属于是将这些琐碎的操作封装了。(java呵呵呵)

Tree newTreeNode(int v){
    Tree T = (Tree)malloc(sizeof(struct TreeNode));
    T -> v = v;
    T -> Left = NULL;
    T -> Right = NULL;
    T -> flag = 0;
    return T;
}

3.插入操作,向二叉搜索树插入数据,这里需要注意的是,这是二叉搜索树,所以我们不仅需要递归到要插入节点相应的位置还要判断此时要插入的这个节点到底比现在的节点小还是大。

//向已经建好的树插入数据
Tree insert(Tree T, int V){
    //如果这个节点开始个控节点就直接插入即可,
    //否则就执行下面的逻辑直到找到自己的位置再插入
    if(!T) T =  newTreeNode(V);
    if(T -> v > V) T->Left = insert( T->Left , V);
    if(T -> v < V) T->Right = insert( T->Right , V);
    return T;
}

 4.最后一步,建立二叉树,初始化完树的根结点,之后的操作就是调用刚才我们定义好的插入操作,将题目中输入的样例一个一个插入进去。

//建立新树
Tree createTree(int N){
    int v;
    cin>>v;
    Tree T = newTreeNode(v);
    for(int i=0 ; i<(N-1) ; i++){
        cin>>v;
        // cout<<v<<endl;
        T = insert(T,v);
    }
    return T;
}

2.如何判别两个二叉搜索树是否一样

  1. 其实如何判断两个二叉树是否一样的问题,我们有很多种解法,但最终我们需要一种比较简单容易实现的方法,因为毕竟我们这是在写题目而不是在搞工程,所以我选择只建立一个树。再遍历其他树的时候,我们一个节点节点判断,采取下面图片这种方法,为啥可以这么判断,看代码

//搜索的顺序和插入的时候一样
int check(Tree T , int V){
    if(T->flag){
        if(V > T->v ) return check( T->Right , V);
            else if(V < T->v ) return check( T->Left , V);
			else return 0;
    }
    else{
        
            if(V == T->v) {
               T -> flag = 1;
                return 1;
            }
			else {
                // cout<<"what"<<endl;
                return 0;
            }
            
    }
}

你有没有发现插入和搜索的代码当我们如果将搜索的操作改为插入那将一模一样,所以说如果在原先建立的二叉搜索树中搜索某个节点的时候,这个节点按照我们搜索的步骤找到了自己应该处于的位置(和插入时一样)。但是发现这个位置的节点和自己不一样,那么就可以判断这两个二叉搜索建出来的树一定不一样。

  2.然后上面的是搜索一个节点的代码,但是我们需要搜索的节点可不止有一个,而是一颗完整的树,所以需要在外面再套层壳子。

int Judge(Tree T, int N){
    int V , i;
    cin>>V;
    int flag = 1;
    if( V!=T->v ){
        flag = 0;
    }else{
		T ->flag =1;
	}

    //为啥设为1,头结点遍历过了。
    for(i=1 ; i<N ; i++){
		cin>>V;
        // cout<<"V:"<<V<<endl;
        if((!check(T,V))&&(flag)){ 
			flag = 0;
		}
    }
    return flag;
}

这里一定要注意的点是,我们在输入下一个搜索二叉树的样例的时候我们一定要将原先那个正在判断的二叉树读完,所以我们这两个地方千万不能像我这样写,因为如果像我这样写就会产生一种情况,我们没有读完原先那个二叉搜索树的样例,使得我们的样例被输入到了其他的变量中,那就会产生我们想象不到的结果。

if( V!=T->v ){
        return 0;
    }else{
		T ->flag =1;
	}
if((!check(T,V))&&(flag)){ 
			return 0;
		}

 至此,这道题讲解完毕,下面是完整的正确代码:

#include <cstddef>
#include <iostream>
using namespace std;


typedef struct TreeNode *Tree;
struct TreeNode{
    int v;
    Tree Left , Right;
    int flag;
};

//和java一样new一个节点
Tree newTreeNode(int v){
    Tree T = (Tree)malloc(sizeof(struct TreeNode));
    T -> v = v;
    T -> Left = NULL;
    T -> Right = NULL;
    T -> flag = 0;
    return T;
}
//向已经建好的树插入数据
Tree insert(Tree T, int V){
    //如果这个节点开始个控节点就直接插入即可,
    //否则就执行下面的逻辑直到找到自己的位置再插入
    if(!T) T =  newTreeNode(V);
    if(T -> v > V) T->Left = insert( T->Left , V);
    if(T -> v < V) T->Right = insert( T->Right , V);
    return T;
}
//建立新树
Tree createTree(int N){
    int v;
    cin>>v;
    Tree T = newTreeNode(v);
    for(int i=0 ; i<(N-1) ; i++){
        cin>>v;
        // cout<<v<<endl;
        T = insert(T,v);
    }
    return T;
}
//遍历的方法和插入的时候一样
int check(Tree T , int V){
    if(T->flag){
        if(V > T->v ) return check( T->Right , V);
            else if(V < T->v ) return check( T->Left , V);
			else return 0;
    }
    else{
        
            if(V == T->v) {
               T -> flag = 1;
                return 1;
            }
			else {
                // cout<<"what"<<endl;
                return 0;
            }
            
    }
}
//判断思路:遍历一遍后面来比较的树,看遍历顺序是否对的上,如果对得上,那么就是同一颗树
//遍历的方法和插入的时候一样。
int Judge(Tree T, int N){
    int V , i;
    cin>>V;
    int flag = 1;
    if( V!=T->v ){
        flag = 0;
    }else{
		T ->flag =1;
	}

    //为啥设为1,头结点遍历过了。
    for(i=1 ; i<N ; i++){
		cin>>V;
        // cout<<"V:"<<V<<endl;
        if((!check(T,V))&&(flag)){ 
			flag = 0;
		}
    }
    return flag;
}


void ResetT(Tree T){
    if(T == NULL) return;
    T -> flag = 0;
    if(T->Left != NULL) ResetT(T->Left);
    if(T->Right != NULL) ResetT(T->Right);
    return;
}

int main(){
    int N,L;
    scanf("%d",&N);
    while(N){
        cin>>L;
        Tree T = createTree(N);
        for(int i=0 ;i<L; i++){

        if(Judge(T,N)) {
            printf("Yes\n");
        }
        else {
            printf("No\n");
        }
        ResetT(T);
        }
        T = NULL;
        scanf("%d",&N);
    }
    return 0;
    
}

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

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

相关文章

使用Serv-U搭建FTP服务器并公网访问

文章目录 1. 前言2. 本地FTP搭建2.1 Serv-U下载和安装2.2 Serv-U共享网页测试2.3 Cpolar下载和安装 3. 本地FTP发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 转载自内网穿透工具的文章&#xff1a;使用Serv-U搭建FTP服务器并公网访问【内网穿透】_ 1. 前言…

linux专题:GDB详细调试方法与实现

系列文章目录 例如&#xff1a;第一章 Linux-GDB 调试实验的使用 文章目录 目录 系列文章目录 文章目录 一、实验目的 二、实验现象 三、实验准备 四、Linux GDB调试实验流程 五、Linux GDB 调试器 总结 一、实验目的 掌握使用 gcc 分步编译 c 代码为可执行程序步骤以及 gc…

【数学建模】步长的选择(优化建模)

人们每天都在行走&#xff0c;排除以运动健身为目的的走路方式&#xff0c;而仅仅考虑距离固定&#xff0c;以节省体力为最终目的的行走&#xff0c;那么选择多大的步长才最省力&#xff1f; 人在走路时所做的功等于抬高人体重心所需的势能与两腿运动所需的动能之和。在给定速度…

又到520了,来画一朵抽搐的玫瑰花吧

文章目录 静态的玫瑰 敲了这么多年代码&#xff0c;每年都得画一些心啊花啊什么的&#xff0c;所以现在常规的已经有些倦怠了&#xff0c;至少也得来个三维图形才看着比较合理&#xff0c;而且光是三维的也没啥意思&#xff0c;最好再加上能动起来。 静态的玫瑰 网上有很多生…

AIGC技术研究与应用 ---- 下一代人工智能:新范式!新生产力!(1-简介)

文章大纲 AI GC参考文献与学习路径模型进化券商研报陆奇演讲AI GC AI模型可大致分为决策式/分析式AI(Discriminant/Analytical AI)和生成式AI (Generative AI)两类。 决策式AI:学习数据中的条件概率分布,根据已有数据进行分析、判断、预测,主要应用模型有用于推荐系 统和…

Elasticsearch 集群部署插件管理及副本分片概念介绍

Elasticsearch 集群配置版本均为8以上 安装前准备 CPU 2C 内存4G或更多 操作系统: Ubuntu20.04,Ubuntu18.04,Rocky8.X,Centos 7.X 操作系统盘50G 主机名设置规则为nodeX.qingtong.org 生产环境建议准备单独的数据磁盘主机名 #各自服务器配置自己的主机名 hostnamectl set-ho…

chatgpt赋能Python-pythonf检验

Python的重要性与应用 Python是一种高级编程语言&#xff0c;因其简单易学和灵活性而备受欢迎。它已经成为数据分析、web开发、机器学习等许多领域的重要工具。在本篇文章中&#xff0c;我们将探讨Python在SEO中的作用。 Python对SEO的影响 SEO是搜索引擎优化的缩写&#xf…

【数据结构】线性表 ⑥ ( 双循环链表 | 双循环链表插入操作 | 双循环链表删除操作 | LinkedList 双循环链表源码分析 )

文章目录 一、双循环链表插入操作处理二、双循环链表删除操作处理三、LinkedList 双循环链表源码分析1、链表节点2、LinkedList 链表中收尾元素指针3、链表插入操作4、链表向指定位置插入操作5、获取指定索引的元素6、删除指定索引的元素 一、双循环链表插入操作处理 双循环链表…

【JVM】6. 堆

文章目录 6.1. 堆&#xff08;Heap&#xff09;的核心概述6.1.1. 堆内存细分6.1.2. 堆空间内部结构&#xff08;JDK7&#xff09;6.1.3. 堆空间内部结构&#xff08;JDK8&#xff09; 6.2. 设置堆内存大小与OOM6.2.1. 堆空间大小的设置6.2.2. OutOfMemory举例 6.3. 年轻代与老年…

[CTF/网络安全] 攻防世界 backup 解题详析

[CTF/网络安全] 攻防世界 backup 解题详析 PHP备份文件名备份文件漏洞成因备份文件名常用后缀姿势总结 题目描述&#xff1a;X老师忘记删除备份文件&#xff0c;他派小宁同学去把备份文件找出来,一起来帮小宁同学吧&#xff01; PHP备份文件名 PHP 脚本文件的备份文件名&#…

【瑞萨RA_FSP】外部中断

文章目录 一、外部引脚中断二、中断过程三、按键外部中断 一、外部引脚中断 1. ICU框图 根据ICU的功能框图可以知道&#xff0c;首先需要配置IRQCR寄存器(IRQ Control Register&#xff0c;IRQ英文全称&#xff1a;Interrupt ReQuest&#xff0c;中文名&#xff1a;中断请求&a…

C++入门篇---(命名空间、缺省参数、以及输入、输出)

前言 c 我来了,恭喜牛牛解锁新世界.开启c的学习之旅. &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>:讲解C…

30年后,茶产业规模是现在的10倍

做个预言&#xff1a;30年后&#xff0c;茶产业是现在的10倍 【5.21是世界茶日】 杭州中国茶博会&#xff0c;我来啦 人工智能越让生产效率越来越高 常用物质将会唾手可得 人闲着&#xff0c;无法体会活着的意义&#xff0c;才是挑战 田园诗茶生活方式会有一席之地 趣讲大白话&…

【EMC专题】案例:读一读TI的按接口选择ESD器件指南

在TI的官网上看到一份ESD by Interface Selection Guide,也就是按接口选择ESD器件指南。因此想读一读看看一起学习一下。 首先看一下文档,是比较简明的。可以看到不同的接口推荐了一些不同的保护器件。因为应用环境不一样,所有有不同的器件封装(如单体、集成TVS等),这样在…

Spyder可在线使用!?

不同安装&#xff0c;如果想使用spyder进行编程&#xff0c;可以用其在线版&#xff0c;和本地版功能一样&#xff0c;就是有点慢。 另外需要用chrome浏览器&#xff0c;用火狐没法正常访问。 Spyder可以在线使用&#xff0c;所以在没有安装python环境的电脑上&#xff0c;想…

Linux常用命令——hostname命令

在线Linux命令查询工具 hostname 显示和设置系统的主机名 补充说明 hostname命令用于显示和设置系统的主机名称。环境变量HOSTNAME也保存了当前的主机名。在使用hostname命令设置主机名后&#xff0c;系统并不会永久保存新的主机名&#xff0c;重新启动机器之后还是原来的主…

字符串匹配--BF算法和KMP算法

0.前言 字符串函数strstr相信大家都不陌生–就是在一个字符串&#xff08;主串&#xff09;中找查找另一个字符串&#xff08;子串&#xff09;&#xff0c;并返回子串在主串中的位置。那么这个函数是怎么实现的呢&#xff1f;这就涉及字符串匹配的问题&#xff0c;本章就让我们…

Node.js 事件循环和事件派发器

目录 1、process.nextTick() 介绍 2、setTimeout() 3、零延迟 4、setInterval() 5、递归setTimeout 6、setImmediate() 7、Node.js 事件派发器 1、process.nextTick() 介绍 Node.js中 process.nextTick函数以一种特殊的方式与事件循环交互。 当你试图理解Node.js事件循…

Redis数据结构——QuickList、SkipList、RedisObjective

承接上文&#xff0c;本文主要介绍QuickList、SkipList、RedisObjective 四、 Redis数据结构-QuickList 问题1&#xff1a;ZipList虽然节省内存&#xff0c;但申请内存必须是连续空间&#xff0c;如果内存占用较多&#xff0c;申请内存效率很低。怎么办&#xff1f; ​ 答&a…

计算机操作系统(慕课版)第二章课后题答案

一、简答题 (1)什么是前趋图&#xff1f;试画出下面四条语句的前趋图. S1&#xff1a;axy&#xff1b; S2&#xff1a;bz1&#xff1b; S3&#xff1a;ca-b&#xff1b; S4&#xff1a;wc1&#xff1b; 答&#xff1a;前趋图(Precedence Graph)是一个有向无循环图&#xff0c;…