数据结构练习题————(二叉树)——考前必备合集!

今天在牛客网力扣上带来了数据结构中二叉树的进阶练习题

1.二叉搜索树与双向链表———二叉搜索树与双向链表_牛客题霸_牛客网 (nowcoder.com)

2.二叉树遍历————二叉树遍历_牛客题霸_牛客网 (nowcoder.com)

3.二叉树的层序遍历————102. 二叉树的层序遍历 - 力扣(LeetCode)

4.二叉树的层序遍历————107. 二叉树的层序遍历 II - 力扣(LeetCode)

5.两个节点的最近公共祖先————236. 二叉树的最近公共祖先 - 力扣(LeetCode)

6.根据二叉树创建字符串————606. 根据二叉树创建字符串 - 力扣(LeetCode)

7.从前序和中序遍历构造二叉树————105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

8.从中序和后序遍历构造二叉树————106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

9.非递归二叉树的前序遍历————144. 二叉树的前序遍历 - 力扣(LeetCode)

1,二叉搜索树与双向链表

描述

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示

数据范围:输入二叉树的节点数 0≤n≤10000≤n≤1000,二叉树中每个节点的值 0≤val≤10000≤val≤1000
要求:空间复杂度O(1)O(1)(即在原树上操作),时间复杂度 O(n)O(n)

注意:

1.要求不能创建任何新的结点,只能调整树中结点指针的指向。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继
2.返回链表中的第一个节点的指针
3.函数返回的TreeNode,有左右指针,其实可以看成一个双向链表的数据结构

4.你不用输出双向链表,程序会根据你的返回值自动打印输出

输入描述:

二叉树的根节点

返回值描述:

双向链表的其中一个头节点。

示例1

输入:

abc##de#g##f###

复制输出:

c b e g d f a 

思路:说实话这题我觉得挺难的,看解答才弄懂,我们要创建的链表的顺序就是二叉树中序遍历的顺序,所以我们用一个中序遍历的方法,在遍历过程中,记录我们前一个节点,让当前节点也前一个节点像链表一样连起来。

public class Solution {public TreeNode Convert(TreeNode pRootOfTree) {TreeNode a = inOrderTree(pRootOfTree);return a;}public static TreeNode head=null;public static TreeNode prev=null;public static TreeNode inOrderTree(TreeNode root){if(root==null){return null;}inOrderTree(root.left);if(prev==null){head = root;prev = root;}else{prev.right = root;root.left = prev;prev = root;}inOrderTree(root.right);return head;} 
}

我们来走一遍,

刚开始,head和prev都为空,我们进行中序遍历,从节点10开始,向左递归,到节点6,向左递归,到节点4,向左递归,到null,返回,我们此时判断prev是否为空,为空,我们把head和prev都设立为当前节点4,我们向右递归,为空,返回,4,全递归完毕,整体返回,到6,6的左节点递归完毕,进行prev判断,不为空,prev的right指向当前节点,当前节点的left指向前一个节点,向右递归,到8节点,8节点向左递归,为空,返回,判断prev,不为空,我们prev已经记录下前一个节点了,让当前节点的left指向前一个节点,前一个节点的right指向下一个当前节点,我们就完成了两个节点的链接,8,向右递归,遇到null,返回,6整体返回,到10,接下来重复这个过程。

注意1一定是对前一个节点进行操作,如果提前对后一个节点进行操作,那么就会丢失,二叉树就找不到节点了。

2,二叉树遍历

描述

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。

输入描述:

输入包括1行字符串,长度不超过100。

输出描述:

可能有多组测试数据,对于每组数据, 输出将输入字符串建立二叉树后中序遍历的序列,每个字符后面都有一个空格。 每个输出结果占一行。

示例1

输入:

abc##de#g##f###

复制输出:

c b e g d f a 

思路:这道题我们要遍历字符串,因为是用先序遍历的方法,所以我们遇到字母的时候就创建节点,##的时候就为空,再对我们创建好的二叉树进行中序遍历。

import java.util.Scanner;class TreeNode{char val;TreeNode left;TreeNode right;public TreeNode(char val){this.val = val;}
}
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);while(in.hasNextLine()){String str = in.nextLine();TreeNode root = createTree(str);inorderTree(root);}}static int i = 0;public static TreeNode createTree(String str){TreeNode b = null;char a = str.charAt(i);if(a!='#'){b = new TreeNode(a);i++;b.left=createTree(str);b.right=createTree(str);}else{i++;return null;}return b;}public static void inorderTree(TreeNode root){if(root==null){return ;}inorderTree(root.left);System.out.print(root.val+" ");inorderTree(root.right);}
}

创建节点和中序遍历的方法就不说了,前几期都详细介绍了嗷,我们直接讲那个创建二叉树,还是刚才那样,一步一步来。

int i我们定义成为静态的因为我们递归的时候不希望他返回的时候没有进行操作,定义静态的就不受影响了,我们从字符串开始看,我们开始i为1,得到的第一个字符是a,a不等于#,我们创建节点A,i++,节点的左边我们开始递归,字符不为#,创建节点,i++,这个节点此时已经与A的左边连上了,我们继续向左递归,字符不为#,i++,创建节点c,与b的左边连上,再向左递归,遇到null,i++,返回null,此时来到c的左边,c向右递归,遇到井号,i++,返回null,返回到b,b向右递归............一直下去。

3,二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]

示例 2:

输入:root = [1]
输出:[[1]]

示例 3:

输入:root = []
输出:[]

 思路:这题不难的,我们之前详细做过二叉树的层序遍历,我们只要用一个引用,和一个队列就OK了,但是这题不一样,他想让我们返回一个类似二维数组的链表

我们只需要之前层序遍历打印元素的时候,提前算出我们要放在每一层的元素个数,再把他们都放到小链表中,最后再放到大链表中。

class Solution {Queue<TreeNode> queue = new LinkedList<TreeNode>();List<List<Integer>> list1 = new LinkedList<>();public List<List<Integer>> levelOrder(TreeNode root) {if(root==null){return list1;}TreeNode cur = root;queue.offer(root);while(!queue.isEmpty()){List<Integer> list2 = new LinkedList<>();int sz = queue.size();for(int i=1;i<=sz;i++){cur = queue.poll();list2.add(cur.val);if(cur.left!=null){queue.offer(cur.left);}if(cur.right!=null){queue.offer(cur.right);}}list1.add(list2);}return list1;}
}

4,二叉树的层序遍历2

给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[[15,7],[9,20],[3]]

示例 2:

输入:root = [1]
输出:[[1]]

示例 3:

输入:root = []
输出:[]

思路:跟刚才的题基本一致,只需要改一个地方,我们已经实现了刚才的二维链表了,我们在每次实现小链表的思路不变,只需要在实现大链表的时候,实现的不是尾插,而是头插即可。 
 

class Solution {Queue<TreeNode> queue = new LinkedList<>();List<List<Integer>> list1 = new ArrayList<>();public List<List<Integer>> levelOrderBottom(TreeNode root) {if(root==null){return list1;}TreeNode cur = null;queue.offer(root);while(!queue.isEmpty()){int sz = queue.size();List<Integer> list2 = new ArrayList<>();while(sz>0){cur = queue.poll();list2.add(cur.val);sz--;if(cur.left!=null){queue.offer(cur.left);}if(cur.right!=null){queue.offer(cur.right);}}list1.add(0,list2);}return list1;}
}

5,两个节点的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

示例 1:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。

示例 2:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。

示例 3:

输入:root = [1,2], p = 1, q = 2
输出:1

这道题我们可以使用两个方法,第一个就是传统的二叉树遍历,第二个方法就是找他们的交点,

第一种方法,思路:我们去遍历这个二叉树,从左树开始完了右树,我们可以分为4种情况。

p或者q就在树的根节点,此时根节点直接就是我们要找的祖先节点。

第二种情况就是p和q在左树和右树的两边,当二叉树从左到右全部递归完毕的时候,我们走到节点,此时判断leftNode和rightNode是否为空,如果不为空,说明当前节点已经是p,q节点的最近公共祖先了,我们只需一直返回它即可,这种情况,一定是根节点,

那这个只能判断根节点,那么这个图怎么弄呢

我们在5节点找到最近公共祖先,返回5节点,3节点左边接收到5节点,但是右边为null,无法输出,所以我们在最后两行判断了这种特殊情况,如果只有左节点或者只有有节点成功获得祖先节点的返回值,我们就输出获得的这个节点,因为我们知道,如果3的左边没有获得q节点,那么它一定是在左边且p节点的下边,因为题目说了一定有p,q节点的。

class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root==null){return root;}if(root.val==p.val || root.val==q.val){return root;}TreeNode leftNode = lowestCommonAncestor(root.left,p,q);TreeNode rightNode = lowestCommonAncestor(root.right,p,q);if(leftNode!=null && rightNode!=null){return root;}if(leftNode!=null){return leftNode;}return rightNode;}
}

 第二种方法,我们想象成两个链表相交的思路

我们遍历二叉树把p和q的长度放到对应的栈中

再让长的那个栈出一个元素,之后两个栈一起出最后剩的一个元素就是我们的最近公共祖先。

class Solution {Stack<TreeNode> stack1 = new Stack<>();Stack<TreeNode> stack2 = new Stack<>();public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root==null){return null;}getpath(root,p,stack1);getpath(root,q,stack2);if(stack1.size()>stack2.size()){Stack<TreeNode> tmp = new Stack<>();tmp = stack1;stack1 = stack2;stack2 = tmp;}while(stack2.size()-stack1.size()>0){stack2.pop();}while(stack1.peek().val != stack2.peek().val){stack1.pop();stack2.pop();}return stack2.pop();}public boolean getpath(TreeNode root,TreeNode p,Stack<TreeNode> stack){if(root==null){return false;}stack.push(root);if(root.val==p.val){return true;}boolean a = getpath(root.left,p,stack);if(a==true){return true;}boolean b = getpath(root.right,p,stack);if(b==true){return true;}stack.pop();return false;}
}

我们看着这个getpath代码走几次,就拿题目中的p=5,q=1, 和p=5,q=4。

我们找q节点

我们从节点3开始将节点3放入stack1中,向左递归,到5节点,将5放到stack1中,向左递归,到节点6,将节点6放到stack1中,向左递归,返回null,向右递归,返回null,将节点6移出stack中,返回5节点,5节点向右递归,到2节点,将2节点放入stack1中,向左递归,遇到节点7,将节点7放到stack中,向左递归,遇到null返回,向右递归,遇到null,返回,将7移出stack,返回到节点2,向右递归,遇到节点4,找到q节点了,返回true,到2节点,返回true,到5,返回true,到3的左边,返回true;找到q节点,p节点同理,当q=1的时候,左边没有一个true,全部都被移出了。

6,根据二叉树创建字符串

给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。

空节点使用一对空括号对 "()" 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

示例 1:

输入:root = [1,2,3,4]
输出:"1(2(4))(3)"
解释:初步转化后得到 "1(2(4)())(3()())" ,但省略所有不必要的空括号对后,字符串应该是"1(2(4))(3)" 。

示例 2:

输入:root = [1,2,3,null,4]
输出:"1(2()(4))(3)"
解释:和第一个示例类似,但是无法省略第一个空括号对,否则会破坏输入与输出一一映射的关系。

 思路:这道题就不是很难了,我们观察每个输入输出的例子,对于每个节点有几个子节点就会在后面出现(对应节点),null也为(),所以的父亲节点都会在()的前面。

class Solution {public static StringBuilder sb;public String tree2str(TreeNode root) {sb = new StringBuilder("");createString(root);String str = sb.toString();return str;}public void createString(TreeNode root){if(root==null){return;}sb.append(root.val);if(root.left!=null){sb.append("(");createString(root.left);sb.append(")");}else{if(root.right==null){return;}else{sb.append("(");sb.append(")");}}if(root.right!=null){sb.append("(");createString(root.right);sb.append(")");}else{return;}}
}

这道题我们用子问题思路,关注每个节点,每次递归时,我们都先把当前节点拼接到字符串上,我们使用StringBuilder来拼接,而不是用string去+,因为在使用String+的时候会创建很多的对象,浪费很多的内存和时间,我们拼接好后判断当前节点左右子节点的情况,在对其进行操作。

7,前序遍历与中序遍历构造二叉树

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

示例 1:

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]

示例 2:

输入: preorder = [-1], inorder = [-1]
输出: [-1]

思路:

 我们是怎么通过先序遍历和中序遍历构建字符串的呢,我们先看前序遍历,因为前序遍历,每次都是先遇到节点,再向左,向右遍历。所以我们创建二叉树的时候也是按照前序遍历的顺序构建节点,接下来就要考虑节点的左右了,我们这时使用中序遍历,把中序遍历的头记为begin,尾记为end,我们先找跟节点,前序遍历的头,在中序遍历中找到前序遍历的头,就是我们的根节点,我们把它的下标记为index。

这时我们再分两边构建两树,左边的begin不变,end变味index-1,右边end不变,begin=index+1

继续递归。

此时左树的end已经小于begin,左树的递归就停止了,右树继续

右树的左子树递归完毕,begin>end,递归右子,

递归全部完毕。

class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {return buildTreeChild(preorder,inorder,0,inorder.length-1);}int i = 0;public TreeNode buildTreeChild(int[] preorder, int[] inorder, int begin, int end){if(begin>end){return null;}TreeNode root = new TreeNode(preorder[i]);int index = FindIndex(preorder,inorder,begin,end);i++;root.left = buildTreeChild(preorder,inorder,begin,index-1);root.right = buildTreeChild(preorder,inorder,index+1,end);return root;}public int FindIndex(int[] preorder,int[] inorder, int begin,int end){for(int j = begin;j<=end;j++){if(preorder[i]==inorder[j]){return j;}}return -1;}
}

 8,从中序与后序遍历构建二叉树

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

示例 1:

输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]

示例 2:

输入:inorder = [-1], postorder = [-1]
输出:[-1]

思路和刚才前序遍历加中序遍历构建二叉树一样。但是我们这次是从后序遍历最后一个下边往前遍历创建节点, 在每次递归时我们都是先创建右树,在左树。

class Solution {public int i;public TreeNode buildTree(int[] inorder, int[] postorder) {i = postorder.length-1;return buildTreeChild(inorder,postorder,0,inorder.length-1);}public TreeNode buildTreeChild(int[] inorder,int[] postorder,int begin,int end){if(begin>end){return null;}TreeNode root = new TreeNode(postorder[i]);int index = findIndex(inorder,postorder,begin,end);i--;root.right = buildTreeChild(inorder,postorder,index+1,end);root.left = buildTreeChild(inorder,postorder,begin,index-1);return root;}public int findIndex(int[] inorder,int[] postorder,int begin,int end){for(int j=begin;j<=end;j++){if(postorder[i]==inorder[j]){return j;}}return -1;}
}

9,非递归的二叉树的前序遍历

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例 1:

输入:root = [1,null,2,3]

输出:[1,2,3]

解释:

示例 2:

输入:root = [1,2,3,4,5,null,8,null,null,6,7,9]

输出:[1,2,4,5,6,7,3,8,9]

解释:

示例 3:

输入:root = []

输出:[]

示例 4:

输入:root = [1]

输出:[1]

 这题我们之前做过我们使用最基础的递归,我们可不可以用迭代做呢

 既然是官方给的,那必须做了。

我们之前用队列实现过层序遍历,其实原理都一样,我们这次使用栈来完成前序遍历。

看这个图,我们把一放到栈中,再把栈中的第一个元素pop到cur中。

把cur右边的元素先放到栈,再放cur左边的栈。再出栈中的第一个元素,如此往复。

class Solution {Stack<TreeNode> stack1 = new Stack<>();List<Integer> list = new LinkedList<>();public List<Integer> preorderTraversal(TreeNode root) {if(root==null){return list;}TreeNode cur  = null;stack1.push(root);while(!stack1.isEmpty()){cur = stack1.pop();if(cur==null){continue;}else{list.add(cur.val);stack1.push(cur.right);stack1.push(cur.left);}}return list;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

寿司检测系统源码分享

寿司检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

一文了解高速工业相机

超高速相机是工业相机的一种&#xff0c;一般高速相机指的是数字工业相机&#xff0c;其一般安装在机器流水线上代替人眼来做测量和判断&#xff0c;通过数字图像摄取目标转换成图像信号&#xff0c;传送给专用的图像处理系统。 超高速工业相机的采集速率> 50Gb/s&#xff…

window系统DockerDesktop 部署windows容器

目录 参考文献1、安装Docker Desktop1.1 下载安装包1.2 安装教程1.3 异常解决 2、安装windows容器2.1 先启动DockerDesktop 软件界面2.2 检查docker版本2.3 拉取windows镜像2.4 网盘下载windows镜像 参考文献 windows容器docker中文官网 Docker: windows下跑windows镜像 1、安…

软件测试标准流程(思维导图版)

一套标准的流程在实际工作落地并执行起来&#xff0c;针对管理可起到很好的作用。 针对效率可在工作中不断的执行&#xff0c;执行后不断的进行优化&#xff0c;再次执行&#xff0c;在不断的工作实践中慢慢完善最终适用于整个团队。 这就是标准流程的作用与实际的好处&#…

华为申请鸿蒙甄选、鸿蒙优选商标,加词的注意!

近日华为在35类广告销售上申请鸿蒙智选、鸿蒙优选、鸿蒙精品&#xff0c;鸿蒙甄选等商标&#xff0c;后面所加的词智选、优选、精品、甄选等基本上是属于通用词。 这样在35类拿到鸿蒙通用词商标&#xff0c;需要先拿到“鸿蒙“商标&#xff0c;经普推知产商标老杨检索发现&…

【Linux】yum、vim、gcc使用(超详细)

目录 yum 安装软件 卸载软件 查看安装包 安装一下好玩的命令 vim vim基本操作 模式切换 命令集 vim批量注释 vim配置 gcc 函数库 小知识点&#xff1a; Linux中常见的软件安装方式 --------- 下载&&安装 a、yum/apt b、rpm安装包安装 c、源码安装 y…

周家庄智慧旅游小程序

项目概述 周家庄智慧旅游小程序将通过数字化手段提升游客的旅游体验&#xff0c;依托周家庄的自然与文化资源&#xff0c;打造智慧旅游新模式。该小程序将结合虚拟现实&#xff08;VR&#xff09;、增强现实&#xff08;AR&#xff09;和人工智能等技术&#xff0c;提供丰富的…

vue嵌套路由刷新页面空白问题

问题描述 在vue项目开发中遇到这样一个问题&#xff0c;在history模式下通过页面点击路由跳转可以打开页面&#xff0c;但是在当前页面刷新就空白了&#xff0c;如下&#xff1a; 点击路由跳转页面是有的 刷新页面就空白 代码 {path: "/home",name: "home&qu…

SQL常用数据过滤 - EXISTS运算符

SQL查询中的EXISTS运算符用于检查查询子句是否存在满足特定条件的记录&#xff0c;如果有一条或者多条记录存在&#xff0c;则返回True&#xff0c;否则返回False。 语法结构 SELECT column_name(s)FROM table_nameWHERE EXISTS(SELECT column_name FROM table_name WHERE co…

React学习笔记(2.0)

React事件绑定 语法&#xff1a;在对应标签上书写on事件&#xff08;比如onClick,onChange&#xff09;&#xff0c;注意和原生的事件区分&#xff0c;React的事件首字母要大写。 const handleChange(e:any)>{console.log(e);console.log(change事件触发);// e不是原生事件…

Acwing 最小生成树

最小生成树 最小生成树:由n个节点&#xff0c;和n-1条边构成的无向图被称为G的一棵生成树&#xff0c;在G的所有生成树中&#xff0c;边的权值之和最小的生成树&#xff0c;被称为G的最小生成树。&#xff08;换句话说就是用最小的代价把n个点都连起来&#xff09; Prim 算法…

初识Jenkins持续集成系统

随着软件开发复杂度的不断提高&#xff0c;团队成员之间如何更好地协同工作以确保软件开发的质量&#xff0c;已经慢慢成为开发过程中不可回避的问题。Jenkins 自动化部署可以解决集成、测试、部署等重复性的工作&#xff0c;工具集成的效率明显高于人工操作;并且持续集成可以更…

Java线程池详解

目录 前言 线程池概述 线程池的实现 线程池的构造 拒绝策略 任务队列 线程池的工作原理 线程池的监控 Executors线程池工厂 自定义线程池 使用线程池的好处 应用场景 总结 本文详细探讨了线程池在并发编程领域的应用&#xff0c;介绍了ThreadPoolExecutor的核心组…

MySQL的登录、访问、退出

一、登录&#xff1a; 访问MySQL服务器对应的命令&#xff1a;mysql.exe ,位置&#xff1a;C:\Program Files\MySQL\MySQL Server 8.0\bin &#xff08;mysql.exe需要带参数执行&#xff0c;所以直接在图形界面下执行该命令会自动结束&#xff09; 执行mysql.exe命令的时候出…

2024年9月26日历史上的今天大事件早读

1620年9月26日 大明皇帝朱常洛驾崩 1815年9月26日 俄、普、奥三国在巴黎发表缔结“神圣同盟” 1841年9月26日 清代思想家、诗人龚自珍逝世 1849年9月26日 “生理学之父”巴甫洛夫诞生 1909年9月26日 云南陆军讲武堂创办 1953年9月26日 画家徐悲鸿逝世 1980年9月26日 国际…

VulnHub-Narak靶机笔记

Narak靶机笔记 概述 Narak是一台Vulnhub的靶机&#xff0c;其中有简单的tftp和webdav的利用&#xff0c;以及motd文件的一些知识 靶机地址&#xff1a; https://pan.baidu.com/s/1PbPrGJQHxsvGYrAN1k1New?pwda7kv 提取码: a7kv 当然你也可以去Vulnhub官网下载 一、nmap扫…

ChatGPT高级语音助手正式上线!OpenAI:50多种语言、9种声线可选

①OpenAI终于要面向其所有付费用户开放ChatGPT的类人高级人工智能&#xff08;AI&#xff09;语音助手功能——“高级语音模式”&#xff08;AVM&#xff09;&#xff1b; ②所有付费订阅ChatGPT Plus和Team计划的用户&#xff0c;都将可以使用新的AVM功能&#xff0c;不过该模…

Tomcat后台弱口令部署war包

1.环境搭建 cd /vulhub/tomcat/tomcat8 docker-compose up -d 一键启动容器 2.访问靶场 点击Manager App tomcat8的默认用户名和密码都是tomcat进行登录 3.制作war包 先写一个js的一句话木马 然后压缩成zip压缩包 最后修改后缀名为war 4.在网站后台上传war文件 上传war文件…

功能测试详解

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、测试项目启动与研读需求文档 &#xff08;一&#xff09; 组建测试团队 1、测试团队中的角色 2、测试团队的基本责任 尽早地发现软件程序、系统或产品中所…

Keil提示main.c(2): warning C318: can‘t open file ‘LCD1602.h‘

应该是创建项目的时候没有手敲.h文件&#xff0c;直接点击下面图片里面红框里面的选项&#xff0c;导致编译的时候keil没有.h文件的目录&#xff0c;所以报错&#xff0c;手动添加.h文件的目录即可。 解决方法&#xff1a; 1.找到该位置。 2.添加路径。&#xff08;路径为自己…