代码随想录刷题题Day11

刷题的第十一天,希望自己能够不断坚持下去,迎来蜕变。😀😀😀
刷题语言:C++ / Python
Day11 任务
● 理论基础
● 递归遍历
● 迭代遍历
● 统一迭代

1 二叉树理论基础

1.1 二叉树的种类

(1)满二叉树
在这里插入图片描述
深度为 k k k,有 2 k − 1 2^k-1 2k1个节点的二叉树
(2)完全二叉树

定义:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h h h 层( h h h 1 1 1开始),则该层包含 1~ 2 h − 1 2^{h-1} 2h1个节点

在这里插入图片描述
优先级队列其实是一个堆,堆就是一棵完全二叉树,同时保证父子节点的顺序关系
(3)二叉搜索树
前面的树,没有数值,而二叉搜索树是有数值的,二叉搜索树是一个有序树

1.若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2.若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3.它的左、右子树也分别为二叉排序树

在这里插入图片描述
(4)平衡二叉搜索树
平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树
在这里插入图片描述
C++中map、set、multimap,multiset的底层实现都是平衡二叉搜索树,所以map、set的增删操作时间时间复杂度是 l o g n logn logn

1.2 二叉树的存储方式

链式存储和顺序存储

顺序存储的元素在内存是连续分布的,而链式存储则是通过指针把分布在各个地址的节点串联一起

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

如果父节点的数组下标是 i i i,左孩子就是 i ∗ 2 + 1 i * 2+1 i2+1,右孩子就是 i ∗ 2 + 2 i * 2+2 i2+2

1.3 二叉树的遍历方式

二叉树主要有两种遍历方式:

  1. 深度优先遍历:先往深走,遇到叶子节点再往回走。
  2. 广度优先遍历:一层一层的去遍历。

深度优先遍历:

  1. 前序遍历(递归法,迭代法)中左右
  2. 中序遍历(递归法,迭代法)左中右
  3. 后序遍历(递归法,迭代法)左右中

这里前中后,其实指的就是中间节点的遍历顺序
在这里插入图片描述
前中后序遍历的逻辑其实都是可以借助栈使用递归的方式来实现的
广度优先遍历

层次遍历(迭代法)

广度优先遍历的实现一般使用队列来实现,这也是队列先进先出的特点所决定的,因为需要先进先出的结构,才能一层一层的来遍历二叉树

这两种遍历是图论中最基本的两种遍历方式

1.4 二叉树的定义

C++:

struct TreeNode {
	int val;
	TreeNode* left;
	TreeNode* right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

Python:

class TreeNode:
	def __init__(self, val, left = None, right = None):
		self.val = val
		self.left = left
		self.right = right

2 递归遍历

递归的三要素:

  1. 确定递归函数的参数和返回值

确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型

  1. 确定终止条件

运行遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出

  1. 确定单层递归的逻辑

确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程

前序遍历:
(1)确定递归函数的参数和返回值

void traversal(TreeNode* cur, vector<int>& vec)

(2)确定终止条件

if (cur == NULL) return;

(3)确定单层递归的逻辑
前序遍历是中左右

vec.push_back(cur->val);   // 中
traversal(cur->left, vec); // 左
traversal(cur->right, vec);// 右

C++:

class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec)
    {
        if (cur == NULL) return;
        vec.push_back(cur->val);   // 中
        traversal(cur->left, vec); // 左
        traversal(cur->right, vec);// 右
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        traversal(root, result);
        return result;
    }
};

Python:

class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        left = self.preorderTraversal(root.left)
        right = self.preorderTraversal(root.right)
        
        return [root.val] + left + right

中序遍历:
C++:

class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec)
    {
        if (cur == NULL) return;
        traversal(cur->left, vec); // 左
        vec.push_back(cur->val);   // 中
        traversal(cur->right, vec);// 右
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        traversal(root, result);
        return result;
    }
};

Python:

class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        left = self.inorderTraversal(root.left)
        right = self.inorderTraversal(root.right)

        return left + [root.val] + right

后序遍历:
C++:

class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec)
    {
        if (cur == NULL) return;
        traversal(cur->left, vec);  // 左
        traversal(cur->right, vec); // 右
        vec.push_back(cur->val);    // 中
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> result;
        traversal(root, result);
        return result;
    }
};

Python:

class Solution(object):
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        left = self.postorderTraversal(root.left)
        right = self.postorderTraversal(root.right)
        return left + right + [root.val]

3 迭代遍历

递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因
用栈也可以实现二叉树的前后中序遍历

3.1 前序遍历(迭代法)

前序遍历是中左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子。

出栈的时候才是中左右的顺序

在这里插入图片描述
C++:

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
		stack<TreeNode*> st;
		vector<int> result;
		st.push(root);
		while (!st.empty())
		{
			TreeNode* node = st.top();// 中
			st.pop();
			if (node != NULL) result.push_back(node->val);
			else continue;
			st.push(node->right);// 右
			st.push(node->left);// 左
		}
		return result;
    }
};

目前的前序遍历的逻辑无法直接应用到中序遍历上

3.2 后序遍历(迭代法)

在这里插入图片描述
C++:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> result;
        st.push(root);
        while (!st.empty())
        {
            TreeNode* node = st.top();
            st.pop();
            if (node != NULL) result.push_back(node->val);
            else continue;
            st.push(node->left);
            st.push(node->right);
        }
        reverse(result.begin(), result.end()); // 将结果反转之后就是左右中的顺序
        return result;
    }
};
3.3 中序遍历(迭代法)

中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),这就造成了处理顺序和访问顺序是不一致的
在使用迭代法写中序遍历,就需要借用指针的遍历来帮助访问节点,栈则用来处理节点上的元素
在这里插入图片描述

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        TreeNode* cur = root;
        stack<TreeNode*> st;
        while (cur != NULL || !st.empty())
        {
            if (cur != NULL)// 指针来访问节点,访问到最底层
            {
                st.push(cur);// 将访问的节点放进栈
                cur = cur->left;// 左
            }
            else
            {
                cur = st.top();// 从栈里弹出的数据,就是要处理的数据
                st.pop();
                result.push_back(cur->val);// 中
                cur = cur->right;// 右
            }
        }
        return result;
    }
};

鼓励坚持十二天的自己😀😀😀

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux----内核及发行版

1. Linux内核 Linux内核是操作系统内部操作和控制硬件设备的核心程序&#xff0c;它是由芬兰人林纳斯开发的。 内核效果图: 说明: 真正操作和控制硬件是由内核来完成的&#xff0c;操作系统是基于内核开发出来的。 2. Linux发行版 是Linux内核与各种常用软件的组合产品&am…

这些Pads技术问题,你还在继续犯错吗?

随着时代发展&#xff0c;Mentor Pads很快成为国内半导体公司的常用EDA软件之一&#xff0c;也就是说起码有数万个电子工程师在使用Pads设计PCB&#xff0c;当然也有很多工程师在使用Pads时遇到了很多问题&#xff0c;下面来看看有哪些技术问题仍然还在继续犯&#xff1f; 1、走…

9:00面试,9:05就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到12月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40…

1840_emacs org-mode babel的语言支持

Grey 全部学习内容汇总&#xff1a; GitHub - GreyZhang/g_org: my learning trip for org-mode 1840_emacs org-mode babel的语言支持 主题由来介绍 Babel是org-mode中支持文学式编程以及可重现研究的一个核心模块&#xff0c;之前看过这个插件的优点是功能完善且支持的语…

20分钟部署ChatGLM3-6B

准备工作 1.下载源代码&#xff1a; https://github.com/THUDM/ChatGLM3 2.下载预训练模型&#xff1a; https://modelscope.cn/models/ZhipuAI/chatglm3-6b/files 可以创建一个py文件&#xff0c;直接使用如下代码下载到本地&#xff1a; from modelscope.hub.snapshot_dow…

出现 Error:Unable to access jarfile xxxx\target\nacos-server.jar 解决方法

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 执行Nacos中的startup.cmd的时候出现闪退,于是在该脚本的最后一行添加pause,查看因为什么原因闪退 出现的bug如下所示:Error:Unable to access jarfile xxxx\target\nacos-server.jar 截图如下所示: 查看内部文件夹,…

壹家人温暖宁夏中卫,34个孩子收到壹基金温暖包

这个12月&#xff0c;2023年度壹基金温暖包在宁夏中卫的发放活动顺利开展&#xff0c;镇罗中学的4个孩子和山羊场小学28个孩子领到了这份温暖的冬日礼物&#xff0c;后续还有丰台村2个孩子也会领到这份冬天的礼物。 2023年壹基金温暖包共筹集温暖包34个&#xff0c;经过我们…

Linux基本操作指令

哈喽小伙伴们&#xff0c;从这篇文章开始&#xff0c;在学习数据结构的同时&#xff0c;我们开启一个新的篇章——Linux操作系统的学习&#xff0c;这将会是又一个新的开始&#xff0c;希望小伙伴们能够认真细心&#xff0c;不要掉队哦。 目录 一.什么是Linux 二.为什么要学习…

QT用户界面隐藏管理员界面部分功能

效果预览 QT用户界面隐藏管理员界面部分功能 GITHUB网站 QT版本 qmake QT core gui sqlGitHub代码获取链接 GitHub代码获取链接

HAT(CVPR 2023):Hybrid Attention Transformer for Image Restoration

HAT ​ 论文地址&#xff1a;HAT: Hybrid Attention Transformer for Image Restoration ​ 代码地址&#xff1a;XPixelGroup/HAT: CVPR2023 - Activating More Pixels in Image Super-Resolution Transformer 摘要 ​ 通过归因分析attribution analysis method - Local …

智慧燃气让城市能源系统高效运行

关键词&#xff1a;智慧燃气、燃气数字化、智慧燃气平台、智慧燃气解决方案、智慧燃气系统 随着我国城镇燃气行业的发展&#xff0c;燃气行业管理及服务从简单的手工运作阶段迈入数字燃气阶段&#xff0c;大量采用信息化手段管理燃气业务&#xff0c;智慧燃气应运而生。它既是…

Web漏洞分析-文件解析及上传(上)

随着互联网的迅速发展&#xff0c;网络安全问题变得日益复杂&#xff0c;而文件解析及上传漏洞成为攻击者们频繁攻击的热点之一。本文将深入研究文件解析及上传漏洞&#xff0c;通过对文件上传、Web容器IIS、命令执行、Nginx文件解析漏洞以及公猫任意文件上传等方面的细致分析&…

k8s-Pod

1、Pod 简介&#xff1a; (1) 概念&#xff1a; Pod 是 Kubernetes 中创建和管理的&#xff0c;最小的可部署的计算单元。Pod中存储了一组&#xff08;一个或多个&#xff09;容器&#xff0c;以及怎样运行这些容器的声明&#xff0c;这些容器共享存储、网络和环境&#xff0…

简易的JS逆向解码

在实战的漏洞挖掘中阅读JS有以下几个作用&#xff1a; 1.JS中存在插件名字&#xff0c;根据插件找到相应的漏洞直接使用 通过控制台大致阅读网站JS代码发现此网页引用了北京的一家公司的代码&#xff0c;并且使用了h-net的框架&#xff0c;接下来我们可以百度这家公司或者是这…

智能优化算法应用:基于水循环算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于水循环算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于水循环算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.水循环算法4.实验参数设定5.算法结果6.参考文…

【精选】SpringMVC简介及其执行流程,参数获取方式

SpringMVC简介 MVC模型 MVC全称Model View Controller&#xff0c;是一种设计创建Web应用程序的模式。这三个单词分别代表Web应用程序的三个部分&#xff1a; Model&#xff08;模型&#xff09;&#xff1a;指数据模型。用于存储数据以及处理用户请求的业务逻辑。在Web应用中&…

C#基础——语法学习

C#的基本语法 在介绍基本语法之前我们先来大概讲一下创建好的这些文件都是做什么的 .sln文件&#xff1a;将项目和解决方案项结合到一起 .vs文件夹&#xff1a;用来存储当前解决方案中关于用户的设置和自定义项&#xff0c;比如断点&#xff0c;主题等。&#xff08;一般都将其…

短信打开小程序

获取 URL Scheme | 微信开放文档 静态网站 H5 跳小程序 | 微信开放文档

阿里云SMC迁移RedHat/CentOS 5 内核升级

阿里云SMC迁移RedHat/CentOS 5 内核升级 1. 起因 服务器需要迁移上阿里云,有几台服务器用的是Redhat 5.x,在使用SMC进行迁移时出现以下报错. [2023-12-13 09:50:55] [Error] Check System Info Failed, codeS16_111, msgGet OS Info Failed: [error] grub is too old for C…

工作随记:long类型数据迁移问题小记

文章目录 概要整体解决方法方法一&#xff1a;用COPY的方法&#xff1a;方法二&#xff1a;PL/SQL(如上)方法三&#xff1a;直接就把LONG转换成CLOB类型方法四&#xff1a;exp/imp 技术过程 概要 工作随记&#xff1a;在做技术方案发现客户数据库的表存在与系统表空间&#xf…