递归--数据结构--黑马

递归

总结一句话,上手直接多刷Leetcode,比看这个更有用。

定义

递归是一种解决计算问题的方法,其中解决方案取决于同一类问题的更小子集。

例如,单链表递归遍历的例子:

void f(Node node) {if (node == null) {return;}f(node.next);
}

说明:

  1. 自己调用自己,如果每个函数对应一个解决方案,自己调用自己意味着解决方案一样(有规律)。
  2. 每次调用,函数处理的数据会较上次缩减(子集),而且最后会缩减至无需继续递归。
  3. 内层函数调用(子集处理)完成,外层函数才能算调用完成。

例如,

// 假如链表是,1 -> 2 -> 3 -> null    
void f(Node node) {if (node == null) {return;}System.out.println("before: " + node.value);f(node.next);System.out.println("after: " + node.value);
}

根据递归的性质,从链表头节点开始遍历,打印第一个节点值 n o d e . v a l u e = 1 node.value=1 node.value=1 ,进入 f ( n o d e . n e x t ) f(node.next) f(node.next) 第二个节点不为空,打印第二个节点值 n o d e . v a l u e = 2 node.value=2 node.value=2 ,进入 f ( n o d e . n e x t ) f(node.next) f(node.next) 到第三个节点(不为null),打印第三个节点值 n o d e . v a l u e = 3 node.value=3 node.value=3 ,进入 f ( n o d e . n e x t ) f(node.next) f(node.next) ,因为当前节点为null,则进入 i f if if 语句,return返回,执行第三次 f f f 函数的输出语句,得到 n o d e . v a l u e = 3 node.value=3 node.value=3 ,然后执行第二次 f f f 函数的输出语句,得到 n o d e . v a l u e = 2 node.value=2 node.value=2 ,最后执行第一次 f f f 函数的输出语句,得到 n o d e . v a l u e = 1 node.value=1 node.value=1

使用伪代码执行流程如下,不考虑语法正确。

// 假如链表是,1 -> 2 -> 3 -> null   
void f(Node node = 1) {System.out.println("before: " + node.value);			// 1void f(Node node = 2) {System.out.println("before: " + node.value);		// 2void f(Node node = 3) {System.out.println("before: " + node.value);	// 3void f(Node node = null) {if (node == null) {return;}}System.out.println("after: " + node.value);		// 3}System.out.println("after: " + node.value);			// 2}System.out.println("after: " + node.value);				// 1
}

简单应用

例1 - 阶乘

用递归方法求阶乘

  • 阶乘定义: n ! = 1 ⋅ 2 ⋅ 3 ⋯ ( n − 2 ) ⋅ ( n − 1 ) ⋅ n n!=1·2·3 \cdots(n-2)·(n-1)·n n!=123(n2)(n1)n ,其中 n n n 为自然数, 0 ! = 1 0!=1 0!=1
  • 递推关系

f ( n ) = { 1 , n = 1 n ∗ f ( n − 1 ) , n > 1 f(n) = \begin{cases} 1, & n=1 \\ n*f(n-1), & n>1 \end{cases} f(n)={1,nf(n1),n=1n>1

public class Factorial {public int f(int n) {if (n == 1) {return 1;}return n * f(n - 1);}
}

例2 - 递归反向打印字符串

public class ReversePrintString{public static void f(int n, String str) {if (n == str.length()) {		// 当n索引等于字符串长度,returnreturn;}f(n + 1, str);System.out.println(str.charAt(n));}public static void main(String[] args) {f(0, "abcd");}
}

例3 - 递归版二分查找

public class BinarySearch {public static int search(int[] a, int target) {return f(a, target, 0, a.length - 1);}// 实现递归的方法private static int f (int[] a, int target, int i, int j) {if (i > j) {// 递归终止条件,未找到return -1;}int m = (i + j) >>> 1;if (target < a[m]) {return f(a, target, i, m - 1);} else if (target > a[m]) {return f(a, target, m + 1, j);} else {return m;}}}

例4 - 递归版冒泡排序

public class BubbleSort{public static void sort (int[] a) {bubble(a, a.length - 1);}private static void bubble(int[] a, int j) {if (j == 0) {return;}for(int i = 0; i < j; i++) {if (a[i] > a[i + 1]) {swap(a, i, i + 1);}}bubble(a, j - 1);}public static void swap(int[] a, int i, int j) {int temp = a[i];a[i] = a[j];a[j] = temp;}
}
递归版冒泡排序改进
public class BubbleSort{public static void sort (int[] a) {bubble(a, a.length - 1);}private static void bubble(int[] a, int j) {if (j == 0) {return;}int x = 0;		// 使用变量x记录下次排序的右边界for(int i = 0; i < j; i++) {if (a[i] > a[i + 1]) {swap(a, i, i + 1);x = i;}}bubble(a, x);}public static void swap(int[] a, int i, int j) {int temp = a[i];a[i] = a[j];a[j] = temp;}
}

或者不使用递归,直接使用循环,如下

public class BubbleSort{public static void sort (int[] a) {int j = a.length - 1;while (true) {int x = 0;		// 使用变量x记录下次排序的右边界for(int i = 0; i < j; i++) {if (a[i] > a[i + 1]) {swap(a, i, i + 1);x = i;}}j = x;if (j == 0) {break;}}}public static void swap(int[] a, int i, int j) {int temp = a[i];a[i] = a[j];a[j] = temp;}public static void main(String[] args) {int[] arr = {9, 8, 7, 6, 5, 4, 3, 2, 1};sort(arr);System.out.println(Arrays.toString(arr));}
}

例5 - 递归版插入排序

public class InsertionSort{public static void sort(int[] a) {insertion(a, 1);}public static void insertion(int[] a, int low) {if (low == a.length) {return;}int t = a[low];int i = low - 1;while (i >= 0 && a[i] > t) {a[i + 1] = a[i];i--;}if (low - 1 != i) {a[i + 1] = t;}insertion(a, low + 1);}}

不使用递归,直接使用循环,如下

public class InsertionSort{public static void sort(int[] a) {for(int low = 1; low < a.length; low++) {int t = a[low];			// 插入的值int i = low - 1;		// 已排序的右边界while (i >= 0 && a[i] > t) {a[i + 1] = a[i];i--;}// 找到插入点,找到比插入值小的索引if (low - 1 != i) {a[i + 1] = t;}}}
}

例6 - 斐波那契数列

递推关系

f ( n ) = { 0 , n = 0 1 n = 1 f ( n − 1 ) + f ( n − 2 ) , n > 1 f(n) =\begin{cases}0,& n=0\\ 1 & n=1 \\ f(n - 1)+f(n-2), & n>1 \end{cases} f(n)= 0,1f(n1)+f(n2),n=0n=1n>1

public class Fibonacci {public static int f(int n) {if (n == 0) {return 0;}if (n == 1) {return 1;}return f(n - 1) + f(n - 2);}
}

改进算法如下,使用空间换时间

public class Fibonacci {public static int fibonacci (int n) {int[] cache = new int[n + 1];Arrays.fill(cache, -1);cache[0] = 1;cache[1] = 1;return f(n, cache);}public static int f (int n, int[] cache) {if (cache[n] != -1) {return cache[n];} cache[n] = f(n - 1) + f(n - 2);return cache[n];}
}

递归时间复杂度计算

Master theorem 主定理

若有递归式
T ( n ) = a T ( n b + f ( n ) ) T(n)=aT(\frac{n}{b} + f(n)) T(n)=aT(bn+f(n))
其中

  • T ( n ) T(n) T(n) 是问题运行的时间, n n n 是数据规模
  • a 是子问题个数
  • T ( n b ) T(\frac{n}{b}) T(bn) 子问题运行的时间,每个子问题被拆成原问题数据规模的 n b \frac{n}{b} bn
  • f ( n ) f(n) f(n) 是除去递归外运行的时间。

x = l o g b a x=log_{b}a x=logba ,即 x = l o g 子问题缩小倍数 x=log_{子问题缩小倍数} x=log子问题缩小倍数 子问题个数

那么
T ( n ) = { Θ ( n x ) f ( n ) = O ( n c ) 并且 c < x Θ ( n x l o g n ) f ( n ) = Θ ( n x ) Θ ( n c ) f ( n ) = Ω ( n c ) 并且 c > x T(n) = \begin{cases} \Theta(n^x) & f(n)=O(n^c)并且c<x\\ \Theta(n^xlogn) & f(n)=\Theta(n^x)\\ \Theta(n^c) & f(n)=\Omega(n^c)并且c>x \end{cases} T(n)= Θ(nx)Θ(nxlogn)Θ(nc)f(n)=O(nc)并且c<xf(n)=Θ(nx)f(n)=Ω(nc)并且c>x

例 1

T ( n ) = 2 T ( n 2 + n 4 ) T(n)=2T(\frac{n}{2} + n^4) T(n)=2T(2n+n4)

  • x = 1 < 4 x=1<4 x=1<4 ,由后者决定时间复杂度 Θ ( n 4 ) \Theta(n^4) Θ(n4)
例 2

T ( n ) = T ( 7 n 10 + n 4 ) T(n)=T(\frac{7n}{10} + n^4) T(n)=T(107n+n4)

  • x = 0 < 1 x=0<1 x=0<1 ,由后者决定时间复杂度 Θ ( n ) \Theta(n) Θ(n)
例 3

T ( n ) = 16 T ( n 4 + n 2 ) T(n)=16T(\frac{n}{4} + n^2) T(n)=16T(4n+n2)

  • x = 2 = 2 x=2=2 x=2=2 ,由前者决定时间复杂度 Θ ( n 2 l o g n ) \Theta(n^2logn) Θ(n2logn)
例 4 - 递归-二分查找
public static int f(int[] a, int target, int i, int j) {int m = (i + j) >>> 1;if (i > j) {return - 1;}if (target < a[m]) {return f(a, target, i, m - 1);} else if (target > a[m]) {return f(a, target, m + 1, j);} else {return m;}
}
  • 子问题个数 a = 1 a=1 a=1
  • 子问题数据规模缩小倍数 b = 2 b = 2 b=2
  • 除递归外执行的计算是常数级 c = 0 c=0 c=0

T ( n ) = T ( n 2 + n 0 ) T(n)=T(\frac{n}{2} + n^0) T(n)=T(2n+n0)

  • 因为 x = 0 = 0 x=0=0 x=0=0 ,时间复杂度为 Θ ( l o g n ) \Theta(logn) Θ(logn)
例 5 - 递归-归并排序
// 伪代码
void split(B[], i, j, A[]) {if (j - i <= 1) {return;}m = (i + j) >>> 1;// 递归split(B[], i, m - 1, A[]);split(B[], m + 1, j, A[]);// 合并merge(B, i, m, j, A);
}
  • 子问题个数 a = 2 a=2 a=2
  • 子问题数据规模缩减倍数 b = 2 b=2 b=2
  • 除递归外,主要时间花在合并上,用 f ( n ) = n f(n)=n f(n)=n 表示;

T ( n ) = 2 T ( n 2 + n ) T(n)=2T(\frac{n}{2} + n) T(n)=2T(2n+n)

  • 因为 x = 1 = 1 x=1=1 x=1=1 ,时间复杂度为 Θ ( n l o g n ) \Theta(nlogn) Θ(nlogn)

展开定理

例 1 - 递归求和
long sum(long n) {if (n == 1) {return 1;}return sum(n - 1) + n;
}

T ( n ) = T ( n − 1 ) + c T(n)=T(n - 1) + c T(n)=T(n1)+c T ( 1 ) = c T(1)=c T(1)=c

如下展开过程

T ( n ) = T ( n − 2 ) + c + c T(n)=T(n - 2) + c + c T(n)=T(n2)+c+c

T ( n ) = T ( n − 3 ) + c + c + c T(n)=T(n - 3) + c + c + c T(n)=T(n3)+c+c+c

⋯ \cdots

T ( n ) = T ( 1 ) + ( n − 1 ) c = n c T(n)=T(1)+(n-1)c=nc T(n)=T(1)+(n1)c=nc

时间复杂度: O ( n ) O(n) O(n)

例 2 - 递归冒泡排序
void bubble(int[] a, int high) {if (high == 0) {return;}for(int i = 0; i < high; i++) {if (a[i] > a[i + 1]) {// 交换swap(a, i, i + 1);}}return bubble(a, high - 1);
}

T ( n ) = T ( n − 1 ) + n T(n)=T(n - 1) + n T(n)=T(n1)+n T ( 1 ) = c T(1)=c T(1)=c

如下展开过程

T ( n ) = T ( n − 2 ) + ( n − 1 ) + n T(n)=T(n - 2) + (n - 1) + n T(n)=T(n2)+(n1)+n

T ( n ) = T ( n − 3 ) + ( n − 1 ) + ( n − 2 ) + n T(n)=T(n - 3) + (n - 1) + (n - 2) + n T(n)=T(n3)+(n1)+(n2)+n

⋯ \cdots

T ( n ) = T ( 1 ) + 2 + ⋯ + n = T ( 1 ) + ( n − 1 ) n + 2 2 = c + n 2 2 + n 2 − 1 T(n)=T(1)+2+\cdots+n=T(1)+(n - 1)\frac{n+2}{2}=c+\frac{n^2}{2}+\frac{n}{2}-1 T(n)=T(1)+2++n=T(1)+(n1)2n+2=c+2n2+2n1

时间复杂度: O ( n 2 ) O(n^2) O(n2)

推导公式网址

推导公式网址
在这里插入图片描述

多路递归

例 1-汉诺塔

public class HanoiTower{static LinkedList<Integer> a = new LinkedList<>();static LinkedList<Integer> b = new LinkedList<>();static LinkedList<Integer> c = new LinkedList<>();static void init(int n) {for (int i = n; i >= 1; i--) {a.addLast(i);}}// n 为圆盘个数// a, 源// b, 借// c, 目标static void move(int n, LinkedList<Integer> a, LinkedList<Integer> b, LinkedList<Integer> c) {if (n == 0) {return;}move(n - 1, a, c, b);			// 借助c盘,将a盘的n-1个移到b盘c.addLast(a.removeLast());		// 将a盘中的最后一个移到c盘move(n - 1, b, a, c);			// 借助a盘,将b盘的n-1个移动到c盘}public void print(){System.out.println("------------");System.out.println(a);System.out.println(b);System.out.println(c);}public static void main(String[] args) {// init(3);// print();			// a=[3, 2, 1], b=[], c=[]// b.addLast(a.removeLast());		// print();			// a=[3, 2], b=[1], c[]init(3);print();move(3, a, b, c);print();}
}

​ 使用展开定理,或者使用公式网址,子问题个数是2,数据规模比原来减少1, T ( n ) = 2 T ( n − 1 ) + c T(n)=2T(n-1)+c T(n)=2T(n1)+c ,中间操作(将a中的最后一个移动到c)看作常数 c c c
在这里插入图片描述

例 2-杨辉三角

public class PascalTriangle {// 返回某个位置的值public static int element(int i, int j) {if (i == 0 || i == j) {return 1;}return element(i - 1, j - 1) + element(i - 1, j);}// 打印空格public void printSpace(int n, int i) {int num = (n - 1 - i) * 2;for(int j = 0; j < num; j++) {System.out.print(" ");}}// 打印前n行的杨辉三角public static void print(int n) {for(int i = 0; i < n; i++) {printSpace(n, i);for(int j = 0; j <= i; j++) {System.out.printf("-%4d", element(i, j)); 	// 左对齐,并占4位}System.out.print();		// 换行处理}}public static void main(String[] args) {print(5);}}

改进杨辉三角,使用二维数组记录已经计算过的每项元素

public class PascalTriangle {// 返回某个位置的值public static int element(int[][] triangle, int i, int j) {if (triangle[i][j] > 0) {return triangle[i][j];}if (i == 0 || i == j) {triangle[i][j] = 1;return 1;}triangle[i][j] = element(triangle, i - 1, j - 1) + element(triangle, i - 1, j)return triangle[i][j];}  // 打印前n行的杨辉三角public static void print(int n) {// 创建二维数组int[][] triangle = new int[n][];for(int i = 0; i < n; i++) {// 初始化每行i+1个元素triangle[i] = new int[i + 1];for(int j = 0; j <= i; j++) {System.out.printf("-%4d", element(triangle, i, j)); 	// 左对齐,并占4位}System.out.print();		// 换行处理}}public static void main(String[] args) {print(5);}}

改进杨辉三角,使用一维数组

public class PascalTriangle { public static void createRow(int[] row, int i) {if (i == 0) {row[0] = 1;return;}for(int j = i; j > 0; j--) {row[j] = row[j] + row[j - 1];}}// 打印前n行的杨辉三角public static void print(int n) {// 初始一维数组int[] triangle = new int[n];for(int i = 0; i < n; i++) {// 计算createRow(row, i);for(int j = 0; j <= i; j++) {System.out.printf("-%4d", element(triangle, i, j)); 	// 左对齐,并占4位}System.out.print();		// 换行处理}}public static void main(String[] args) {print(5);}}

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

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

相关文章

Ubuntu18.04 配置EtherCAT主站IGH SOEM

IGH IGH 是开源的EtherCAT 主站软件 一、安装依赖 sudo apt update sudo apt install build-essential linux-headers-$(uname -r) mercurial autoconf libtool 也不知道安装的完全不完全 uname -r 可以查看内核&#xff0c;我安装的ubuntu18.04的内核版本是 5.4.0-84-gen…

Koa商城项目-轮播图模块(后端)

前言 通过这次独自做前后端发现有很多需要提升的地方&#xff0c;很多细节处理不到位。下面简单看一下本人自己做的效果吧~~ Git地址 https://gitee.com/ah-ah-bao/koa_system 效果图 后端逻辑分析 首先编写route->banner.router.js /*** author: zxb* date: 2024-08-06…

k8s 部署polardb-x集群

前言 体验了基于源码构建的部署polardb-x 单机部署&#xff0c;当然也想体验性能更好的完全分布式集群。这边文章将重点介绍如何部署polardb-x集群 简介 PolarDB-X 是一款面向超高并发、海量存储、复杂查询场景设计的云原生分布式数据库系统。其采用 Shared-nothing 与存储计…

二叉树详解(1)

文章目录 目录1. 树的概念及结构1.1 树的相关概念1.2 树的表示1.3 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 2. 二叉树的概念及结构2.1 概念2.2 特殊的二叉树2.3 二叉树的存储结构 3. 二叉树的顺序结构及实现3.1 二叉树的顺序结构3.2 堆的概念及结构…

Ubuntu基础使用

1.首先我们先获取ubuntu的操作相同其中也分为4部分&#xff1a; 1.云服务器。在服务器里面我们可以去选择3种服务器分别为阿里云&#xff0c;腾讯云&#xff0c;华为云&#xff0c;这3个&#xff0c;有服务器才可以进去进行操作。 2.双系统。双系统有一个特点就是只能同时启动一…

机器学习:线性回归算法(一元和多元回归代码)

1、线性回归 1、数据准备&#xff1a; 描述如何获取和准备数据。 2、图像预处理&#xff1a; 包括图像读取。 3、将数据划分为训练集和测试集。 4、计算数据的相关系数矩阵。 5、模型训练&#xff1a; 详细说明如何使用线性回归算法训练模型&…

AI视频创作原理

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

打卡学习Python爬虫第二天|Web请求过程刨析

一、服务器渲染 服务器端渲染&#xff08;Server-Side Rendering&#xff0c;简称SSR&#xff09;是一种网页渲染技术。在这种技术中&#xff0c;服务器在接收到客户端的请求后&#xff0c;会生成页面的初始HTML内容&#xff0c;并将其发送给客户端。客户端浏览器接收到这些HT…

Go Roadmap-Basics中文笔记

Go Roadmap-Basics 地址&#xff1a;https://roadmap.sh/golang 简介&#xff1a;Github star No.6 学习路线 Go 中译版 Learn the Basics Go特点&#xff1a;静态类型&#xff0c;运行速度快&#xff0c;编译语言&#xff0c;编译速度快&#xff0c;自动垃圾回收&#xff…

Linux中查看修改系统系统时间

当我们项目部署在Linux中&#xff0c;随着服务器运行时间变长&#xff0c;会出现Linux服务器时间变快或者变慢的情况&#xff0c;有些系统对时间准确性要求比较高&#xff0c;笔者有碰到某天服务器突然无法调用第三方接口&#xff0c;最终排查后系统时间超过15分钟&#xff0c;…

SAR靶机笔记

SAR 靶机笔记 概述 SAR 是 Vulnhub 上的靶机&#xff0c;大家可以去 vulnhub 网站上去进行下载。 这里有链接&#xff1a; https://download.vulnhub.com/sar/sar.zip 一丶常规的 nmap 扫描 1&#xff09;主机发现 sn 只做 ping 扫描&#xff0c;不做端口扫描 nmap -sn …

Linux - 基础工具使用

文章目录 一、yum1、介绍2、功能3、语法4、使用 二、rzsz1、安装rzsz的指令2、介绍3、使用 三、vim基础使用1、介绍2、基础使用 四、gcc/g使用1、生成可执行文件过程2、语法3、常用选项4、编译过程5、动静态库6、包含头文件的多文件编译7、链接外部库 一、yum 1、介绍 Linux中…

类和对象(下)(1)

类和对象&#xff08;下&#xff09; 再探构造函数 我们之前在实现构造函数的时候&#xff0c;初始化成员变量使用的方式都是在函数体内进行赋值&#xff0c;其实构造函数初始化成员变量还有一种方式&#xff1a;初始化列表。 初始化列表不只是为了写得方便&#xff0c;还能解…

构建具有音频功能的中英翻译器:一个Python应用程序的旅程

在当今的全球化世界中&#xff0c;语言翻译工具变得越来越重要。作为一名软件开发者&#xff0c;我最近完成了一个有趣的项目&#xff1a;一个结合了翻译、文字转语音和数据管理功能的中英翻译器。在这篇博客中&#xff0c;我将分享这个应用程序的主要特性和开发过程中的一些见…

【k8s从节点报错】error: You must be logged in to the server (Unauthorized)

k8s主节点可以获取nodes节点信息&#xff0c;但是从节点无法获取&#xff0c;且报错“error: You must be logged in to the server (Unauthorized)” 排查思路&#xff1a; 当时证书过期了&#xff0c;只处理的主节点的证书过期&#xff0c;没有处理从节点的 kubeadm alpha …

基于Windows系统和‌Linux系统,以tomcat为案例,讲解如何新增自启动服务。

文章目录 引言‌I Linux系统‌(以CentOS为例)基础知识:运行级别(run level)基于chkconfig 工具,设置服务启动类型。基于systemctl 新增系统服务制定定时任务优化停止Tomcat服务命令II 基于Windows系统设置服务自启动的常规操作安装多个tomcat服务,并设置自启动。引言 场景…

Vue UI - 可视化的Vue项目管理器

概述 Vue CLI 3.0 更新后&#xff0c;提供了一套全新的可视化Vue项目管理器 —— Vue UI。所以要想使用它&#xff0c;你的 Vue CL I版本必须要在v3.0以上。 一、启动Vue UI 1.1 环境准备 1.1.1 安装node.js 访问官网&#xff08;外网下载速度较慢&#xff09;或 http://nod…

【HeadFirst 设计模式】装饰者模式的C++实现

一、案例背景 Starbuzz是以扩张速度最快而闻名的咖啡连锁店。如果你在街角看到它的店&#xff0c;在对面街上肯定还会看到另一家。因为扩张速度实在太快了&#xff0c;他们准备更新订单系统&#xff0c;以合乎他们的饮料供应要求。他们原先的类设计是这样的…… 购买咖啡时&am…

西安旅游系统--论文pf

TOC springboot383西安旅游系统--论文pf 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。在互联网诞生之前&#xff0c;地域位置往往是人们思想上不可跨域的鸿…

Linux快捷方式创建、输出重定向(正确输出和错误输出)

一.正确输出 创建一个1.txt文件&#xff0c;然后用vim打开这个文件&#xff0c;然后再开一个窗口 进程号是5602 通过proc可以看到5602这个进程 进入5602里面这里记录了程序的信息&#xff0c;找到fd 进入fd目录下面有0124快捷方式&#xff1a;快捷方式对应的真正的文件是 /de…