【数据结构之排序算法】

数据结构学习笔记---010

  • 数据结构之排序算法
    • 1、排序的基本概念及其运用
      • 1.1、常见排序算法的实现
    • 2、插入排序的实现
      • 2.1、直接插入排序
        • 2.1.1、直接插入排序的实现
          • 2.1.1.1、直接插入排序InsertSort.h
          • 2.1.1.2、直接插入排序InsertSort.c
          • 2.1.1.3、直接插入排序main.c
        • 2.1.2、直接插入排序的小结
      • 2.2、希尔排序
        • 2.2.1、希尔排序的实现
          • 2.2.1.1、希尔排序ShellSort.h
          • 2.2.1.2、希尔排序ShellSort.c
          • 2.2.1.3、希尔排序main.c
        • 2.2.2、希尔排序的小结
    • 3、选择排序的实现
      • 3.1、直接选择排序
        • 3.1.1、直接选择排序的实现
          • 3.1.1.1、直接选择排序SelectSort.h
          • 3.1.1.2、直接选择排序SelectSort.c
          • 3.1.1.3、直接选择排序main.c
        • 3.1.2、直接选择排序的小结
      • 3.2、堆排序
        • 3.2.1、堆排序的实现
          • 3.2.1.1、堆排序HeapSort.h
          • 3.2.1.2、堆排序HeapSort.c
          • 3.2.1.3、堆排序main.c
        • 3.2.2、堆排序的小结
    • 4、交换排序的实现
      • 4.1、冒泡排序
        • 4.1.1、冒泡排序的实现
          • 4.1.1.1、冒泡排序BubbleSort.h
          • 4.1.1.2、冒泡排序BubbleSort.c
          • 4.1.1.3、冒泡排序main.c
        • 4.1.2、冒泡排序的小结
      • 4.2、快速排序
        • 4.2.1、快速排序的实现
          • 4.2.1.1、快速排序QuickSort.h
          • 4.2.1.2、快速排序QuickSort.c
          • 4.2.1.3、快速排序main.c
        • 4.2.2、快速排序的小结
    • 5、计数和归并排序的实现
      • 5.1、计数排序
        • 5.1.1、计数排序的实现
          • 5.1.1.1、计数排序CountSort.h
          • 5.1.1.2、计数排序CountSort.c
          • 5.1.1.3、计数排序main.c
        • 5.1.2、计数排序的小结
      • 5.2、归并排序
        • 5.2.1、归并排序的实现
          • 5.2.1.1、归并排序MergeSort.h
          • 5.2.1.2、归并排序MergeSort.c
          • 5.2.1.3、归并排序main.h
        • 5.2.2、归并排序的小结
    • 6、排序算法复杂度及稳定性分析
      • 6.1、归并排序AllSort.h
      • 6.2、归并排序AllSort.c
      • 6.3、归并排序main.c
    • 7、排序算法总结

数据结构之排序算法

前言:
前篇学习了 数据结构的二叉树的知识,那么这篇继续学习关于数据结构的排序算法知识。

/知识点汇总/

1、排序的基本概念及其运用

记录:在排序问题中,通常将数据元素称为记录。
排序:所谓的排序,就是使一串记录,按照其中某个关键字的大小,递增或递减的排序起来的操作。
稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i] = t[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍然在r[j]之前,则称这种排序算法是稳定的。否则称为不稳定的。
正序、逆序:若待排序的记录序列已排好序,称此纪录序列为正序;若待排序列记录的排序顺序与排好序的顺序正好相反,称此纪录序列为逆序或反序。
:在排序过程中,将待排序的记录序列扫描一遍称为一趟。
内部排序:数据元素全部放在内存中的排序。
外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

运用
生活中各种排序的需求场景。 比如,学校成绩排名,物品的销量排名等。

1.1、常见排序算法的实现

常见排序算法的实现分类
1.插入排序:直接插入排序,希尔排序
2.选择排序:选择排序,堆排序
3.交换排序:冒泡排序,快速排序
4.计数和归并排序:计数排序、归并排序

2、插入排序的实现

插入排序:已知一组数据,插入数据使其逐次有序。
插入排序是一种简单的插入排序法其基本思想
待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列

2.1、直接插入排序

直接插入排序是指插入排序中最简单的排序方法,类似于玩纸牌时整理手中纸牌的过程,其基本思想是依次将待排序序列中的每一个记录插入已知排好的序列中,直到全部都排好序。
存在以下两个关键性问题:
1.如何构造初识的有序序列?
2.如何查找待插入的有序序列?

当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移

2.1.1、直接插入排序的实现

直接插入排序的实现:普遍采用类似于分治的思想,先控制好单趟排序。先局部再整体。
声明和定义分离
直接插入排序InsertSort.h
直接插入排序InsertSort.c
直接插入排序main.c

2.1.1.1、直接插入排序InsertSort.h

放置头文件,函数声明,注释信息。后面的头文件同理,不多赘述。

#include  <stdio.h>
//直接插入排序
void InsertSort(int* a, int n);
//打印数据元素
void PrintArray(int* a, int n);
2.1.1.2、直接插入排序InsertSort.c

根据分治思想,所以先思考编写单趟的思路,直接插入的算法思想就是将一个新元素,在已经有序的序列中,去进行比较再插入的操作。但是我们一开始并不知道要插入的序列是否有序,那么不妨假设 [0,end] 闭区间为有序的序列,继续将end+1作为要插入的新元素。所以,不管我们一开始的初识序列是否有序,能确定的是只有第一个元素那么肯定有序,然后再根据假设的区间进行比较插入操作,再后移插入之后的元素即可,所以单趟的思路就是如此。
简述核心就是,将end+1的元素与end的元素比较,大就直接插入在end后面,有序序列范围就是[0,end+1];否则,小就将end右移,范围[0,end].单趟的比较插入就是这样。多趟就是在前面的基础上,逐步n次(n为问题的规模)循环即可。
为了方便理解,画出单趟的图形演示,如下图所示
在这里插入图片描述

边界考虑:当end+1下标的新元素,比有序序列的首元素都小,那么就得考虑边界问题,避免非法访问等问题。
在这里插入图片描述
单趟插入代码实现

//单趟
void InsertSortByOnce(int* a, int len)
{//假设有序序列:[0,end]//新元素下标:end+1int end;int tmp = a[end + 1];//保存新元素值至变量tmp//边界while (end >= 0){//比较end下标的元素的大小if (tmp < a[end]){a[end + 1] = a[end];//后移--end;//更新继续比较的下标}else //tmp >= a[end]{break;}}//尾插,同时解决end移到了 end = -1的情况三。a[end + 1] = tmp;
}

多趟插入代码实现
多趟只需要把单趟执行循环衔接起来即可。end的初始值与序列的数据个数相关,所以end = i;其次,多趟循环的边界,因为下标从0开始那么应该是在n-1结束,防止越界,又因为参数是传入的数组长度。

#include "InsertSort.h"//直接插入排序 -- O(N^2)
void InsertSort(int* a, int n)
{for (int i = 0; i < n-1; i++)//结束位置n-1,满足防止越界{int end = i;int tmp = a[end + 1];while (end >= 0){if (tmp < a[end]){a[end + 1] = a[end];--end;}else{break;}}//同时解决end移到了 end = -1的情况。a[end + 1] = tmp;}
}//打印数据元素
void PrintArray(int* a, int n)
{for (int i = 0; i < n; i++){printf("%d ", a[i]);}printf("\n");
}
2.1.1.3、直接插入排序main.c
#include "InsertSort.h"int main()
{int arr[] = { 3,1,4,6,2,8,5,0,7,10 ,6};InsertSort(arr, sizeof(arr) / sizeof(arr[0]));PrintArray(arr, sizeof(arr) / sizeof(arr[0]));return 0;
}

测试运行结果
在这里插入图片描述

2.1.2、直接插入排序的小结

1.元素集合越接近有序,直接插入排序算法的实践效率越高;
2.时间复杂度为:O(n^2) 最好情况是:O(N) --> 默认顺序恰好有序
3.稳定性:稳定

2.2、希尔排序

希尔排序就是对直接插入排序的改进。希尔排序通过引入“增量”概念,将整个待排序的记录序列分割成若干子序列分别进行直接插入排序,从而减少数据移动的次数,提高排序效率。
基本思想:先确定一个增量gap,是将整个待排序记录序列分割为若干个gap长度的子序列,在子序列内分别进行直接进行插入排序重复上述分组和排序的工作,待整个序列基本有序,gap=1时再对全部记录进行一次直接插入排序
存在两个关键性问题;
1.应如何分割待排序记录,才能保证整个序列逐步向基本有序发展?
2.子序列内如何进行直接插入排序?

2.2.1、希尔排序的实现

希尔排序的实现:普遍采用于分治的思想,先控制好单趟排序。即先局部再整体。
声明和定义分离
直接插入排序ShellSort.h
直接插入排序ShellSort.c
直接插入排序main.c

两个步骤
步骤1.预排序(使接近有序) – 引入gap增量划分为若干组,再分别每组进行插入排序;
gap取得越大,待排序序列中大的值更快调到后面,小的值更快调到前面,但越不接近于有序;
gap取得越小调得越慢,但是越接近有序;
当gap == 1 时就是直接插入排序了。
步骤2.预排序后,最后统一进行,直接插入排序。

那么如何决定gap的大小呢?
首先肯定不是定值,也可以发现gap常常随着问题规模而变化;
所以总结出来一般有两种方法:关键在于始终要保证gap最后都能化为1。
根据数的奇偶性:gap /= 2(gap>1) 或者gap /= 3 + 1

2.2.1.1、希尔排序ShellSort.h
#include  <stdio.h>
//希尔排序
void ShellSort(int* a, int n);
//打印数据元素
void PrintArray(int* a, int n);
2.2.1.2、希尔排序ShellSort.c

根据分治思想,首先得思考单趟的排序处理,而且希尔的主要核心思想就是上述的两个步骤,即根据gap执行预排序,当gap=1时,再执行直接插入排序。
那么单趟的思路:首先确定一个gap值(这里以gap=3为演示),然后将待排序的序列按照gap为间距进行分组,再然后将每组分别进行直接插入排序(注意:并没有改变每组元素各个下标,只在各自组内下标位置间进行插入排序),最后在根据组数进行边界考虑,分析是否越界的情况。边界恰好是每组越界前的元素下标是每组的最后一个元素,所以得出结论,边界控制为n-gap

为了方便理解,画出单趟的图形演示,如下图所示
在这里插入图片描述

单趟希尔代码实现

//单趟思路实现
void ShellSortByOnce(int* a, int n)
{//单趟for (int j = 0; j < gap; j++)//gap组{//第一组,i=0//i = j,j巧妙决定了为第几组for (int i = j; i < n - gap; i += gap) //相当于全局替1为--> gap{int end = i;int tmp = a[end + gap];//每组各个元素间距gapwhile (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;}}
}

明白了单趟的思路,那么多趟就是循环嵌套,其中值得注意的是,这里单趟只是为了方便演示数据gap取的定值3,但是实际应用中,gap是非定值,所以关于gap具体怎么取?以及gap取多少合适?
书上说,关键在于始终要保证gap最后都能化为1。
所以,提供两种常用的方法:根据数的奇偶性:gap /= 2(gap>1) 或者gap /= 3 + 1

多趟希尔代码实现

//希尔排序
void ShellSort(int* a, int n)
{//int gap = 3;int gap = n;while (gap > 1)//直至gap等于1.执行最后一次直接插入排序,完成排序{//gap = gap / 2;gap = gap / 3 + 1;//单趟for (int j = 0; j < gap; j++)//gap组{//第一组//i = j,j巧妙决定了为第几组for (int i = j; i < n - gap; i += gap) //相当于全局替1为--> gap{int end = i;int tmp = a[end + gap];while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;}}}
}

当然还有更加新奇的实现思路,巧妙地运用各组各元素和gap的关系,实现多组并排反复横跳进行比较交换数据的操作,具体可以看我下面画的演示图:
在这里插入图片描述

多组并排希尔代码实现

//希尔排序
//写法2:优化算法 -- 多组并排
void ShellSort(int* a, int n)
{//int gap = 3;int gap = n;while (gap > 1){//gap = gap / 2;gap = gap / 3 + 1;for (int i = 0; i < n - gap; i++) //i++决定了依次反复切换不同组进行插入排序{//单趟int end = i;int tmp = a[end + gap];while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;}}
}
//打印数据元素
void PrintArray(int* a, int n)
{for (int i = 0; i < n; i++){printf("%d ", a[i]);}printf("\n");
}

可知,多组并排与各个组排的关键区别就在于 i++ 和 i += gap。

2.2.1.3、希尔排序main.c
#include "ShellSort.h"int main()
{int arr[] = { 3,1,4,6,2,8,5,0,7,10 ,6};ShellSort(arr, sizeof(arr) / sizeof(arr[0]));PrintArray(arr, sizeof(arr) / sizeof(arr[0]));return 0;
}

测试运行结果
在这里插入图片描述

2.2.2、希尔排序的小结

希尔排序的特性总结:
1.希尔排序就是对直接插入排序的改进。
2.当增量gap>1时,都是预排序,目的是让数组更接近于有序;当gap == 1时,数组已经接近于有序的了,这样就会很快。这样整体而言,可以达到优化效果。
3.希尔排序的时间复杂度不好确定(通过大量数据测试大约处于O(N^1.3),因为根据实际情况的增量并不相同,所以根据书上说的,希尔提出的最早方法是:d1= [n/2] d(i+1) = [di/2],且增量序列互质,显然最后一个增量必须是1。
4.稳定性:所以也就得出该排序算法并不稳定。

3、选择排序的实现

选择排序基本思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在起始位置,直到全部待排序的数据元素排完。

3.1、直接选择排序

直接选择排序(简单选择排序)是选择排序中最简单的排序方法;
其基本思想:是从第i趟排序在待排序r[i]~r[n]中选取最小或最大的数据元素;若它不是这组元素中的最后一个(或第一个)元素,则将它与这组元素中的最后一个(第一个)元素进行交换;并在剩余的数组集合中,重复直到剩余最后一个元素。
存在两个关键性问题:
1.如何在待排序中选出最小的记录?
2.如何确定待排序序列中的最小记录在有序序列中的位置?

3.1.1、直接选择排序的实现

直接插入排序的实现:根据直接选择的思想,得要明确对最大值或最小值的处理,以及比较和交换。
声明和定义分离
直接选择排序SelectSort.h
直接选择排序SelectSort.c
直接选择排序main.c

3.1.1.1、直接选择排序SelectSort.h
#include  <stdio.h>//直接选择排序
void SelectSort(int* a, int n);
//打印数据元素
void PrintArray(int* a, int n);
3.1.1.2、直接选择排序SelectSort.c

首先,知道选择排序的思想,直接选择,最大值或最小值,然后分别放在最左边的位置或最右边的位置,那么既然如此就设计一个区间,以分治的思想一个区间一个区间的,完成每一个区间的最小值和最大值,再分别放入当前区间的最小位置和最大位置。依次类推完成排序即可。
为了方便理解,画出图形大致演示一下,如下图所示
在这里插入图片描述
直接选择排序代码实现

#include "SelectSort.h"//直接选择排序   最好的情况:O(N^2)
static void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}
void SelectSort(int* a, int n)
{int begin = 0;int end = n - 1;while (begin < end){int mini = begin;int maxi = begin;for (int i = begin + 1; i <= end; i++){if (a[i] < a[mini]){mini = i;}if (a[i] > a[maxi]){maxi = i;}}Swap(&a[begin], &a[mini]);if (maxi == begin){maxi = mini;}Swap(&a[end], &a[maxi]);++begin;--

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

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

相关文章

【MySQL】多表关系的基本学习

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-3oES1ZdkKIklfKzq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

【双指针】:Leetcode611.有效三角形的个数

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本专栏是关于各种算法的解析&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数据结构专栏&…

Linux操作系统基础(十二):yum软件包管理器

文章目录 yum软件包管理器 一、yum常用命令 二、yum在线安装软件案例 三、yum在线删除软件案例 yum软件包管理器 yum&#xff08; Yellow dog Updater, Modified&#xff09;是一个在 Fedora 和 RedHat中的 Shell 前端软件包管理器。基于RPM包管理&#xff0c;能够从指定的…

Java基于微信小程序的畅阅读微信小程序

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

CS50x 2024 - Lecture 6 - Python

00:00:00 - Introduction 00:01:01 - Python print("hello world")与c的显著差异 1.不必显式包含标准库 2.不再需要定义main函数 00:07:24 - Speller 00:13:41 - Filter from PIL import Image, ImageFilterbefore Image.open("bridge.jpg") after…

h5和微信小程序实现拍照功能(其中h5暂时无法调用闪光灯)

代码如下 <template><view class"camera"><!-- #ifdef MP --><camera ref"myCamera" id"myCamera" device-position"back" :flash"flash" error"error" style"display: block;"&…

《中国教育报》2024投稿攻略

《中国教育报》2024投稿攻略 《中国教育报》普通版&#xff0c;1800字符1/4版&#xff0c;2300字符1/3版&#xff1b;周期1-2个月 《中国教育报》理论版 收中小学&#xff0c;全包1800字符&#xff1b;2500字符。收高校 2000-2300字符&#xff0c;六个月周期。 《中国教育…

人工智能学习与实训笔记(一):零基础理解神经网络

人工智能专栏文章汇总&#xff1a;人工智能学习专栏文章汇总-CSDN博客 本篇目录 一、什么是神经网络模型 二、机器学习的类型 2.1 监督学习 2.2 无监督学习 2.3 半监督学习 2.4 强化学习 三、网络模型结构基础 3.1 单层网络 ​编辑 3.2 多层网络 3.3 非线性多层网络…

C++11---(1)

目录 一、C11简介 二、列表初始化 2.1、{ } 初始化 三、变量类型推导 3.1、auto 3.2、decltype 为什么需要decltype 四、final和override 4.1、final 4.2、override 五、默认成员函数控制 5.1、default修饰函数 5.2、delete修饰函数 六、nullptr 一、C11简介 C11是…

【STM32 CubeMX】STM32中断体系结构

文章目录 前言一、中断体系的比喻二、中断的内部结构2.1 EXTI触发方式 2.2 NVIC2.3 cpu与中断2.4 外部中断控制器框图上升沿触发选择寄存器屏蔽/使能寄存器等待处理寄存器 2.5 中断优先级 总结 前言 一、中断体系的比喻 STM32中断体系如下图所示&#xff1a; 一座大型建筑物…

STM32F1 - 系统时钟SysTick

SysTick 1> SysTick硬件框图2> SysTick的时钟源3> 1ms定时_中断方式4> 思考&#xff1a;无符号数 0 - 255 ?相关资料 1> SysTick硬件框图 SysTick属于Cotex-M3&#xff0c;是CPU外设&#xff1b; SysTick: 位宽24bit&#xff0c; 递减计数&#xff0c;自动重装…

让你的资金运动起来,金钱的聪明处理方式

一、教程描述 本套教程主要讲解了金融思维和财务思维&#xff0c;常见投资工具的实操技巧&#xff0c;资产配置方案的制定方法&#xff0c;等等&#xff0c;将会重构你现有的投资观念&#xff0c;提升你认知的宽度和深度&#xff0c;可以轻松读懂财经新闻&#xff0c;不仅学会…

spring boot3登录开发-2(1图形验证码接口实现)

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 前置条件 内容简介 图形验证码接口实现 导入糊涂工具依赖 接口分析 编写验证码接口 测试验证码接口 前置条件 …

2024年通信安全员ABC证证模拟考试题库及通信安全员ABC证理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年通信安全员ABC证证模拟考试题库及通信安全员ABC证理论考试试题是由安全生产模拟考试一点通提供&#xff0c;通信安全员ABC证证模拟考试题库是根据通信安全员ABC证最新版教材&#xff0c;通信安全员ABC证大纲整理…

【Linux 04】编辑器 vim 详细介绍

文章目录 &#x1f308; Ⅰ 基本概念&#x1f308; Ⅱ 基本操作1. 进入 / 退出 vim2. vim 模式切换 &#x1f308; Ⅲ 命令模式1. 光标的移动2. 复制与粘贴3. 剪切与删除4. 撤销与恢复 &#x1f308; Ⅳ 底行模式1. 保存文件2. 查找字符3. 退出文件4. 替换内容5. 显示行号6. 外…

ElementUI Form:Cascader 级联选择器

ElementUI安装与使用指南 Cascader 级联选择器 点击下载learnelementuispringboot项目源码 效果图 el-cascader.vue&#xff08;Select选择器&#xff09;页面效果图 项目里el-cascader.vue代码 <script> let id 0; export default {name: el_cascader,data() {re…

线性代数的本质 2 线性组合、张成的空间、基

基于3Blue1Brown视频的笔记 一种新的看待方式 对于一个向量&#xff0c;比如说&#xff0c;如何看待其中的3和-2&#xff1f; 一开始&#xff0c;我们往往将其看作长度&#xff08;从向量的首走到尾部&#xff0c;分别在x和y上走的长度&#xff09;。 在有了数乘后&#xff0…

Netty中的适配器、Handler共享和资源管理

ChannelHandler的适配器 有一些适配器类可以将编写自定义的ChannelHandler所需要的工作降到最低限度&#xff0c; 因为它们提供了定义在对应接口中的所有方法的默认实现。因为有时会忽略那些不感兴趣的 事件&#xff0c;所以Netty提供了抽象积累ChannelInboundHandlerAdapter(…

OpenCV 4基础篇| OpenCV简介

目录 1. 什么是OpenCV2. OpenCV的发展历程3. 为什么用OpenCV4. OpenCV应用领域5. OpenCV的功能模块5.1 基本模块5.2 扩展模块5.3 常用函数目录 1. 什么是OpenCV OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习软件库。它…

BUGKU-WEB bp

题目描述 题目截图如下&#xff1a; 进入场景看看&#xff1a; 解题思路 提示说&#xff1a;弱密码top1000&#xff1f;z???(爆破?)先看看源码有没有提示 相关工具 Burp Suit 爆破top1000字典&#xff0c;点击下载 解题步骤 随便测试账号密码admin、admin 得到提…