《二叉搜索树OJ》

news2024/12/24 7:40:22

文章目录

  • 1、 [根据二叉树创建字符串](https://leetcode.cn/problems/construct-string-from-binary-tree/)
  • 2、 [二叉树的层序遍历](https://leetcode.cn/problems/binary-tree-level-order-traversal/)
  • 3、 [二叉树的层序遍历 II](https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/)
  • 4、 [二叉树的最近公共祖先](https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/)
  • 5、 [二叉搜索树与双向链表](https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/)
  • 6、 [从前序与中序遍历序列构造二叉树](https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/)
  • 7、 [从中序与后序遍历序列构造二叉树](https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/)
  • 8、 [二叉树的前序遍历-非递归](https://leetcode.cn/problems/binary-tree-preorder-traversal/)
  • 9、 [二叉树的中序遍历-非递归](https://leetcode.cn/problems/binary-tree-inorder-traversal/)
  • 10、 [二叉树的后序遍历-非递归](https://leetcode.cn/problems/binary-tree-postorder-traversal/)


1、 根据二叉树创建字符串

在这里插入图片描述

思路图解:
在这里插入图片描述

//对于根节点,直接省略
//递归左边:
//1、左为空,右不为空不省略
//2、左不为空,不省略

//递归右边
//3、右不为空不能省略
    string tree2str(TreeNode* root) 
    {
        if(root == nullptr)
            return "";
        string str = to_string(root->val);
        if(root->left || root->right)
        {
            str += '(';
            str += tree2str(root->left);
            str += ')'; 
        }
        if(root->right)
        {
            str += '(';
            str += tree2str(root->right);
            str += ')';
        }
        return str;
    }

2、 二叉树的层序遍历

在这里插入图片描述

在这里插入图片描述

vector<vector<int>> levelOrder(TreeNode* root)
    {
        vector<vector<int>> vv;
        if(root == nullptr)
            return vv;
        queue<TreeNode*> Qdata; //存储数据的队列

        Qdata.push(root);
        int levelSize = 1;
        while(!Qdata.empty())
        { 
            vector<int> v;
            while(levelSize--)
            {
                 TreeNode* front = Qdata.front();
                 Qdata.pop();
                 v.push_back(front->val);

                 if(front->left)
                    Qdata.push(front->left);
                 if(front->right)
                    Qdata.push(front->right);
            }
            vv.push_back(v);
            levelSize = Qdata.size();
        }
        return vv;
    }

3、 二叉树的层序遍历 II

在这里插入图片描述
思路:直接将从头层序遍历的结果倒过来即可

vector<vector<int>> levelOrderBottom(TreeNode* root) 
    {
        vector<vector<int>> vv;
        queue<TreeNode*> q1; //节点
        int levelSize = 0;

        if(root != nullptr)
        {
            q1.push(root);
            levelSize = 1;
            
        }
        while(!q1.empty())
        {
            vector<int> v;
            while(levelSize--)
            {
                TreeNode* front = q1.front();
                q1.pop();

                
                v.push_back(front->val);

                if(front->left)
                    q1.push(front->left);
                if(front->right)
                    q1.push(front->right);
            }
            levelSize = q1.size();
            vv.push_back(v);
        }
        reverse(vv.begin(),vv.end());//将结果翻转
        return vv;
    }

4、 二叉树的最近公共祖先

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

    bool GetPath(TreeNode* root, TreeNode* x,stack<TreeNode*>& path)
    {
        if(root == nullptr)
            return false; 
        //先入栈在判断
        path.push(root);
        //当前节点就是,直接返回
        //当前节点不是再去左边和右边找
        if(root == x)
            return true;
        
        bool Inleft = GetPath(root->left, x,path);
        if(Inleft)    
            return true; //在左边说明这个节点是路径节点,入栈成功

        bool Inright = GetPath(root->right, x,path);
        if(Inright)    
            return true; //在左边说明这个节点是路径节点,入栈成功
        
        //到这里说明不是路径节点
        path.pop();
        return false;
    }


    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        stack<TreeNode*> ppath;
        stack<TreeNode*> qpath;
        
        GetPath(root,p,ppath);
        GetPath(root,q,qpath);

        while(ppath.size() != qpath.size())
        {
            if(ppath.size() > qpath.size())
                ppath.pop();
            else
            {
                qpath.pop();
            }
        }

        while(ppath.top() != qpath.top())
        {
            ppath.pop();
            qpath.pop();
        }
        return ppath.top();
    }

5、 二叉搜索树与双向链表

在这里插入图片描述

在这里插入图片描述

	void InOrder(TreeNode* cur,TreeNode*& prev)
	{
		if(cur == nullptr)
			return;
		InOrder(cur->left,prev);
		//开始操作
		cur->left = prev;
		if(prev)
			prev->right = cur;
		prev = cur;

		InOrder(cur->right,prev);
	}


    TreeNode* Convert(TreeNode* pRootOfTree) 
	{
        if(pRootOfTree == nullptr)
			return nullptr;
		TreeNode* prev = nullptr;
		InOrder(pRootOfTree,prev);

		//找头
		TreeNode* head = pRootOfTree;
		while(head && head->left)
		{
			head = head->left;
		}
		return head;
	}

6、 从前序与中序遍历序列构造二叉树

在这里插入图片描述
在这里插入图片描述

//思路:前序遍历确定跟,根据根的值在中序遍历中分割左右区间,链接在根的左右两侧,
 //然后递归下去

    TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder,int& prei,int inbegin,int inend)
    {
        if(inbegin > inend)
            return nullptr;
        TreeNode* root = new TreeNode(preorder[prei]);
        //在中序中找根的位置
        int rooti = inbegin;
        while(inbegin <= inend)
        {
            if(preorder[prei] == inorder[rooti])
                break;
            else
                ++rooti;
        }
        ++prei; //下一个根
        //链接
        root->left = _buildTree(preorder, inorder,prei,inbegin,rooti-1);
        root->right = _buildTree(preorder, inorder,prei,rooti+1,inend);

        return root;
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) 
    {
        int i = 0;
        return _buildTree(preorder,inorder,i,0,inorder.size()-1);
    }

7、 从中序与后序遍历序列构造二叉树

在这里插入图片描述
在这里插入图片描述

TreeNode* _buildTree(vector<int>& inorder, vector<int>& postorder,int& posti,int inbegin,int inend) 
    {
        if(inbegin > inend)
            return nullptr;
        //先创建一个根
        TreeNode* root = new TreeNode(postorder[posti]);

        //找到根,将中序序列分割为左右子区间
        int rooti = inbegin;
        while(rooti <= inend)
        {
            if(inorder[rooti] == postorder[posti])
                break;
            else
                rooti++;
        }

        posti--;
        //链接[inbegin,rooti-1] rooti [rooti+1,inend]
        //先链接右子树,因为后序遍历是 左子树 右子树 根
        //从后向前就是根 右子树 左子树
        root->right = _buildTree(inorder, postorder,posti,rooti+1,inend);
        root->left = _buildTree(inorder, postorder,posti,inbegin,rooti - 1);
        
        return root;
    }


    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) 
    {
        int i = postorder.size() - 1;
        return _buildTree(inorder, postorder,i,0,inorder.size() - 1); 
    }

8、 二叉树的前序遍历-非递归

在这里插入图片描述

在这里插入图片描述

//将一棵树看成是左路节点和左路节点的右子树
//首先定义一个数组用来保存结果,定义一个栈,用来保存左路节点
//因为是前序遍历,首先将左路节点入数组和栈,直到cur是空结束了,
//然后取得栈顶元素,将栈顶的右子树给他(其实就是右路节点),循环出栈即可
    vector<int> preorderTraversal(TreeNode* root) 
    {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        while(cur || !st.empty())
        {
            //开始访问一棵树
            //左路节点
            //左路节点的右子树
            while(cur)
            {
                v.push_back(cur->val);
                st.push(cur);
                cur = cur->left;
            }

            //开始访问右子树
            TreeNode* top = st.top();
            st.pop();

            cur = top->right; //子问题访问右子树

        }
        return v;
    }

9、 二叉树的中序遍历-非递归

在这里插入图片描述
在这里插入图片描述

 vector<int> inorderTraversal(TreeNode* root) 
    {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        while(cur || !st.empty())
        {
            while(cur)
            {
                st.push(cur);
                cur = cur->left;
            }
            TreeNode* top = st.top();
            st.pop();
            v.push_back(top->val);

            cur = top->right;//子问题访问右子树
        }
        return v;
    }

10、 二叉树的后序遍历-非递归

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

vector<int> postorderTraversal(TreeNode* root) 
    {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        TreeNode* prev = nullptr;
        while(cur || !st.empty())
        {
            //左路节点入栈
            while(cur)
            {
                st.push(cur);
                cur = cur->left;
            }

            TreeNode* top = st.top();
            
            if(top->right == nullptr || top->right == prev)
            {
                v.push_back(top->val);
                st.pop();
                prev = top;
            }
            else
            {
                //子问题访问左路节点
                cur = top->right;
            }
        }
        return v;
    }

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

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

相关文章

5.3 Python高级特性之-列表生成式、生成器、迭代器

一、 列表生成式 是Python内置的非常简单却强大的可以用来创建list的生成式 具体可根据如下案例理解&#xff0c;且代码也是可用的""" 1、 生成[0,1,2,3,4,5,6]这样列表 """ print(list(range(0, 7))) """ 2、 生成[0&#xff0…

MyBatis入门案列

MyBatis入门案列 开发Mybatis程序的步骤&#xff1a; 1、配置mybatis conf.xml: 配置数据库信息 和 需要加载的映射文件 &#xff12;、表 - 类 映射文件xxMapper.xml: 增删改查标签<select> &#xff13;、测试类: session.selectOne(“需要查询的SQL的namespace.id”…

jenkins 采用ssh方式连接gitlab连接不上

一、gitlab 添加jenkins服务器的公钥 jenkins 生成秘钥命令 ssh-keygen -t rsa2.jenkins 秘钥地址&#xff1a; cd /root/.ssh3.复制公钥 到gitlab 添加 cat id_rsa_pub4.添加私钥到jenkins cat id_rsa5.绑定&#xff08;顺利的话到这里就结束了&#xff09; &#xff0…

oc基本控件2

// // ViewController.m // OcDemoTest // // Created by Mac on 2023/7/14. //#import "ViewController.h"interface ViewController () // label property (weak, nonatomic) IBOutlet UIImageView *imageView; // Use of undeclared identifier // 全局propert…

基于Open3D的点云处理11-三维点云表面重建

点云表面重建 &#xff08;1&#xff09;显式建模方法&#xff1a; Explicit reconstruction 例如&#xff1a;Delaunay 三角网、Alpha shapes &#xff08;2&#xff09;隐式建模方法&#xff1a; Implicit reconstruction 例如&#xff1a;径向基函数法、移动最小二乘法、泊…

【QT】——Base64加解密

介绍 用 记事本 打开 exe、jpg、pdf 这些文件时&#xff0c;我们都会看到一大堆乱码&#xff0c;因为二进制文件包含很多无法显示和打印的字符。如果要让记事本这样的文本处理软件 能 处理二进制数据&#xff0c;如使用 json 保存二进制信息&#xff0c;需要先把数据先做一个 …

微服务 云原生:搭建 K8S 集群

为节约时间和成本&#xff0c;仅供学习使用&#xff0c;直接在两台虚拟机上模拟 K8S 集群搭建 踩坑之旅 系统环境&#xff1a;CentOS-7-x86_64-Minimal-2009 镜像&#xff0c;为方便起见&#xff0c;直接在 root 账户下操作&#xff0c;现实情况最好不要这样做。 基础准备 关…

数据在内存中的存储1(C语言进阶)

数据在内存中的存储 1.数据类型介绍1.1类型的基本归类&#xff1a;整形家族浮点数家族构造类型指针类型空类型 2.整形在内存中的存储2.1 原码、反码、补码2.2 大小端介绍为什么有大端和小端&#xff1a; 我们今天来学习数据在内存中的存储 1.数据类型介绍 前面我们已经学习了基…

TCP三次握手四次挥手

文章目录 TCP 三次握手和四次挥手1、三次握手过程image-202307100943094972、为什么要三次握手3、第 2 次握手传回了 ACK&#xff0c;为什么还要传回 SYN&#xff1f;4、断开连接-TCP 四次挥手5、为什么要四次挥手6、丢包问题7、为什么不能把服务器发送的 ACK 和 FIN 合并起来&…

qt开发技巧之嵌入式linux qt按钮点击触发两次

1.问题 移植qt5.12.9到嵌入式linux系统&#xff0c;tslib作为触摸输入&#xff0c;开发平台是imx6ull&#xff0c;点击pushbutton按钮会出现触发两次点击的情况。 2.解决 vi /etc/profile&#xff0c;在 /etc/profile里添加环境变量&#xff0c;禁止QT自带输入检测&#xff0…

vue-watch监听器

1. 概述 watch是 vue 中常用的监听器&#xff0c;它主要用于侦听数据的变化&#xff0c;在数据发生变化的时候执行一些操作。 Vue官网很明确的建议我们这样使用watch侦听属性&#xff1a;当需要在数据变化时执行异步或开销较大的操作时&#xff0c;这个方式是最有用的。 2. 用…

【通览一百个大模型】XLNet(Google)

XLNet 欢迎订阅阅读【大模型&NLP&算法】。 作者&#xff1a;王嘉宁本文章内容为转载或整理&#xff1b;仓库链接&#xff1a;https://github.com/wjn1996/LLMs-NLP-Algo 【通览一百个大模型】XLNet&#xff08;Google&#xff09; 作者&#xff1a;王嘉宁&#xff0…

lua脚本语言学习笔记

Lua 是一种轻量小巧的脚本语言&#xff0c;用标准C语言编写并以源代码形式开放&#xff0c; 其设计目的是为了嵌入应用程序中&#xff0c;从而为应用程序提供灵活的扩展和定制功能。 因为我们使用redis的时候一般要写lua脚本&#xff0c;这篇文章就介绍一下lua脚本语言的基础用…

Python 算法基础篇:时间复杂度和空间复杂度简介

Python 算法基础篇&#xff1a;时间复杂度和空间复杂度简介 引言 1. 时间复杂度 a ) 常见的时间复杂度 b ) 时间复杂度示例 2. 空间复杂度 a ) 常见的空间复杂度 b ) 空间复杂度示例 结论 引言 在学习和分析算法时&#xff0c;时间复杂度和空间复杂度是两个关键概念。它们帮助…

【Python】类型注解 ④ ( 函数类型注解 | 函数形参类型注解语法 | 函数返回值类型注解 )

文章目录 一、函数形参类型注解1、函数中由于类型缺省导致的提示问题2、函数形参类型注解语法3、代码示例 - 函数形参类型注解 二、函数返回值类型注解1、函数返回值类型注解语法2、代码示例 - 函数返回值类型注解 一、函数形参类型注解 1、函数中由于类型缺省导致的提示问题 由…

LSTM对比Bi-LSTM的电力负荷时间序列预测(Matlab)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

小程序api的promise化

小程序根目录cmd运行安装命令 npm install --save miniprogram-api-promise1.0.4 安装完成之后先到根目录中删除miniprogram_npm文件夹(不删除构建npm时可能会出现问题) 删除之后再在工具中点击构建npm 构建成功之后会看到根目录中重新出现了miniprogram_npm文件夹 在app.j…

P1747 好奇怪的游戏

好奇怪的游戏 题目背景 《爱与愁的故事第三弹shopping》娱乐章。 调调口味来道水题。 题目描述 爱与愁大神坐在公交车上无聊&#xff0c;于是玩起了手机。一款奇怪的游戏进入了爱与愁大神的眼帘&#xff1a;***&#xff08;游戏名被打上了马赛克&#xff09;。这个游戏类似…

修复漏洞(三)升级Docker里面的镜像(MySQL、Nginx等)

前言 因原版本检测出来存在漏洞&#xff0c;故需升级底层镜像 步骤 先看看自己现在的是什么版本&#xff0c;教你们一个骚操作&#xff0c;查看Docker里面的Mysql或者其他容器版本都不用百度出来的这么麻烦首先docker images&#xff0c;查看镜像ID然后docker inspect 镜像I…

2、Java入门教程【IDEA】

1、下载 IDEA社区版&#xff1a;下载地址 IDEA管理JAVA程序的结构&#xff1a; project 项目、工程module 模块package 包class 类 2、创建工程 创建【project】 点击【create】后&#xff0c;项目结构如下&#xff1a; 创建【package】 我们继续在【src】目录下创建【pack…