Day_44希尔排序

news2024/11/24 1:00:10

目录

一. 关于希尔排序

二. 希尔排序的实现过程

三. 希尔排序的代码实现

        1. 核心代码

        2. 修改后的代码

四. 代码展示

五. 数据测试

六. 总结与反思


一. 关于希尔排序

       希尔排序按其设计者希尔(Donald Shell)的名字命名,该算法由希尔在 1959 年所发表的论文“A high-speed sorting procedure”中所描述。1961年,IBM 公司的女程序员 Marlene Metzner Norton(玛琳·梅茨纳·诺顿)首次使用 FORTRAN 语言编程实现了希尔排序算法。在其程序中使用了一种简易有效的方法设置希尔排序所需的增量序列:第一个增量取待排序记录个数的一半,然后逐次减半,最后一个增量为 1。该算法后来被称为 Shell-Metzner 算法。

        希尔排序可以说是排序算法里面最特别的一种存在,它是集合了直接插入算法的两种特殊情况改进而来。我们对直接插入排序进行讨论:例如若待排序列为“正序”时,其时间效率可以提升至O(n),由此可见直接插入更适用于①基本有序②数据量不大的表。希尔排序正是基于这两点分析对直接插入排序进行改进而来,又称缩小增量排序。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

        1. 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。

        2. 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。

        (最特别的是希尔排序的平均时间复杂度是O(n^{1.3}),这在排序算法里面几乎是最具有辨识度的存在)

二. 希尔排序的实现过程

        希尔排序的的基本思想是:先将待排序表分割成若干形如L[i,i+d,i+2d...i+kd]的“特殊”子表,即把相隔某个“增量”的记录组成一个子表,对各个子表分别进行直接插入排序,当整个表中的元素已呈“基本有序”时,再对全体记录进行一次直接插入排序。

        希尔排序的过程如下:先取一个长度小于n的步长d_{1},把表中的全部记录分成d_{1}组,所有距离为d_{1}倍数的记录放在同一组,在各组内部进行直接插入排序;然后取第二个步长d_{2}<d_{1},重复上述过程,直到所取到的d_{t}=1,即所有记录已放在同一组中,再进行直接插入排序,由于此时已经具有较好的局部性,故可以很快得到最终的结果。

        第一趟排序结果如图所示:

第一趟排序结果

        第二趟排序结果如图所示:

第二趟排序结果

         第三趟排序结果如图所示:

第三趟排序结果

三. 希尔排序的代码实现

        1. 核心代码

                第一层循环是确定步长的大小和进行多少次步长的更新;第二层循环是确定一个步长内有多少组数据;第三个循环和第四个循环是对同一个步长里面同一组的数据直接插入排序。这里和书上的有点不同,这里用了四次循环,后面我将再讨论和书上的不同。

    /**
     *********************
     * Shell sort. We do not use sentries here because too many of them are needed.
     *********************
     */
    public void shellSort() {
        DataNode tempNode;
        int[] tempJumpArray = { 5, 3, 1 };
        int tempJump;
        int p;
        for (int i = 0; i < tempJumpArray.length; i++) {
            tempJump = tempJumpArray[i];
            for (int j = 0; j < tempJump; j++) {
                for (int k = j + tempJump; k < length; k += tempJump) {
                    tempNode = data[k];
                    // Find the position to insert.
                    // At the same time, move other nodes.
                    for (p = k - tempJump; p >= 0; p -= tempJump) {
                        if (data[p].key > tempNode.key) {
                            data[p + tempJump] = data[p];
                        } else {
                            break;
                        } // Of if
                    } // Of for p

                    // Insert.
                    data[p + tempJump] = tempNode;
                } // Of for k
            } // Of for j
            System.out.println("Round " + i);
            System.out.println(this);
        } // Of for i
    }// Of shellSort

        2. 修改后的代码

        这里用的三重循环,第一重循环和上面其实是一样的,只不过闵老师用了一个确定的数组来设定步长,我是根据数据长度来设定的步长。

        最重要的是第二重和第三重循环这里等同于上面的第二,三,四重循环。不一样的地方在于我是对于同一步长分类完成之后直接插入排序,而闵老师是根某一个步长先将数据分成几个小组,再将同一个小组的数据进行直接插入排序;相当于后面修改的代码将闵老师的第二,三重循环合并了。

    /**
     *********************
     * Shell sort. We do not use sentries here because too many of them are needed.
     *********************
     */
    public void shellSort1() {
        DataNode tempNode;
        int tempJump;
        int position;
        int i;
        int round=1;

        for (tempJump = length / 2; tempJump >= 1; tempJump = tempJump / 2) {
            for (position = tempJump;  position< length; position += 1) {
                tempNode = data[position];
                // Find the position to insert.
                // At the same time, move other nodes.
                for (i = position - tempJump; i >= 0&&tempNode.key<data[i].key; i -= tempJump) {
                    data[i+tempJump]=data[i];
                } // Of for i
                // Insert.
                data[i + tempJump] = tempNode;
            } // Of for position

            System.out.println("Round " + round);
            System.out.println(this);
            round++;
        }
    }// Of shellSort

四. 代码展示

        主类:

package Day_44;

import Day_41.DataArray;



import Day_41.DataArray;

    public class demo1 {
        /**
         *********************
         * The entrance of the program.
         *
         * @param args Not used now.
         *********************
         */
        public static void main(String args[]) {
//        System.out.println("\r\n-------sequentialSearchTest-------");
            int []paraKeyArray;
            paraKeyArray=new int[]{11,2,3};
            String[] paraContentArray = new String[]{"121","21","324"};
            DataArray test=new DataArray(paraKeyArray,paraContentArray);

//        test.insertionSort();
//        System.out.println("Result\r\n" + test);
            test.shellSortTest();


        }// Of main
    }

        调用类(我喜欢将同一个类的代码写到一起,这样虽然长一点,但是更全面):

package Day_41;
/**
 * Data array for searching and sorting algorithms.
 *
 * @author Jian An 2569222191@qq.com.
 */
public class DataArray {
    /**
     * An inner class for data nodes. The text book usually use an int value to
     * represent the data. I would like to use a key-value pair instead.
     */
    class DataNode {
        /**
         * The key.
         */
        int key;

        /**
         * The data content.
         */
        String content;

        /**
         * ********************
         * The first constructor.
         * ********************
         */
        DataNode(int paraKey, String paraContent) {
            key = paraKey;
            content = paraContent;
        }// Of the first constructor

        /**
         * ********************
         * Overrides the method claimed in Object, the superclass of any class.
         * ********************
         */
        public String toString() {
            return "(" + key + ", " + content + ") ";
        }// Of toString
    }// Of class DataNode

    /**
     * The data array.
     */
    DataNode[] data;

    /**
     * The length of the data array.
     */
    int length;

    /**
     * ********************
     * The first constructor.
     *
     * @param paraKeyArray     The array of the keys.
     * @param paraContentArray The array of contents.
     *                         ********************
     */
    public DataArray(int[] paraKeyArray, String[] paraContentArray) {
        length = paraKeyArray.length;
        data = new DataNode[length];

        for (int i = 0; i < length; i++) {
            data[i] = new DataNode(paraKeyArray[i], paraContentArray[i]);
        } // Of for i
    }// Of the first constructor

    /**
     * ********************
     * Overrides the method claimed in Object, the superclass of any class.
     * ********************
     */
    public String toString() {
        String resultString = "I am a data array with " + length + " items.\r\n";
        for (int i = 0; i < length; i++) {
            resultString += data[i] + " ";
        } // Of for i

        return resultString;
    }// Of toString

    /**
     * ********************
     * Sequential search. Attention: It is assume that the index 0 is NOT used.
     *
     * @param paraKey The given key.
     * @return The content of the key.
     * ********************
     */
    public String sequentialSearch(int paraKey) {
        data[0].key = paraKey;

        int i;
        // Note that we do not judge i >= 0 since data[0].key = paraKey.
        // In this way the runtime is saved about 1/2.
        // This for statement is equivalent to
        //for (i = length - 1; data[i].key != paraKey; i--);
        for (i = length - 1; data[i].key != paraKey; i--) {
            ;
        }//Of for i
        return data[i].content;
    }// Of sequentialSearch

    /**
     * ********************
     * Test the method.
     * ********************
     */
    public static void sequentialSearchTest() {
        int[] tempUnsortedKeys = {-1, 5, 3, 6, 10, 7, 1, 9};
        String[] tempContents = {"null", "if", "then", "else", "switch", "case", "for", "while"};
        DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

        System.out.println(tempDataArray);

        System.out.println("Search result of 10 is: " + tempDataArray.sequentialSearch(10));
        System.out.println("Search result of 5 is: " + tempDataArray.sequentialSearch(5));
        System.out.println("Search result of 4 is: " + tempDataArray.sequentialSearch(4));
    }// Of sequentialSearchTest

    /**
     * ********************
     * Binary search. Attention: It is assume that keys are sorted in ascending
     * order.
     *
     * @param paraKey The given key.
     * @return The content of the key.
     * ********************
     */
    public String binarySearch(int paraKey) {
        int tempLeft = 0;
        int tempRight = length - 1;
        int tempMiddle = (tempLeft + tempRight) / 2;

        while (tempLeft <= tempRight) {
            tempMiddle = (tempLeft + tempRight) / 2;
            if (data[tempMiddle].key == paraKey) {
                return data[tempMiddle].content;
            } else if (data[tempMiddle].key <= paraKey) {
                tempLeft = tempMiddle + 1;
            } else {
                tempRight = tempMiddle - 1;
            }
        } // Of while

        // Not found.
        return "null";
    }// Of binarySearch

    /**
     * ********************
     * Test the method.
     * ********************
     */
    public static void binarySearchTest() {
        int[] tempSortedKeys = {1, 3, 5, 6, 7, 9, 10};
        String[] tempContents = {"if", "then", "else", "switch", "case", "for", "while"};
        DataArray tempDataArray = new DataArray(tempSortedKeys, tempContents);

        System.out.println(tempDataArray);

        System.out.println("Search result of 10 is: " + tempDataArray.binarySearch(10));
        System.out.println("Search result of 5 is: " + tempDataArray.binarySearch(5));
        System.out.println("Search result of 4 is: " + tempDataArray.binarySearch(4));
    }// Of binarySearchTest

//    ----------------------------------------------------
//    ----------------------------------------------------
//    ----------------------------------------------------


    /**
     *********************
     * The second constructor. For Hash code only. It is assumed that
     * paraKeyArray.length <= paraLength.
     *
     * @param paraKeyArray     The array of the keys.
     * @param paraContentArray The array of contents.
     * @param paraLength       The space for the Hash table.
     *********************
     */
    public DataArray(int[] paraKeyArray, String[] paraContentArray, int paraLength) {
        // Step 1. Initialize.
        length = paraLength;
        data = new DataNode[length];

        for (int i = 0; i < length; i++) {
            data[i] = null;
        } // Of for i

        // Step 2. Fill the data.
        int tempPosition;

        for (int i = 0; i < paraKeyArray.length; i++) {
            // Hash.
            tempPosition = paraKeyArray[i] % paraLength;

            // Find an empty position
            while (data[tempPosition] != null) {
                tempPosition = (tempPosition + 1) % paraLength;
                System.out.println("Collision, move forward for key " + paraKeyArray[i]);
            } // Of while

            data[tempPosition] = new DataNode(paraKeyArray[i], paraContentArray[i]);
        } // Of for i
    }// Of the second constructor

    /**
     *********************
     * Hash search.
     *
     * @param paraKey The given key.
     * @return The content of the key.
     *********************
     */
    public String hashSearch(int paraKey) {
        int tempPosition = paraKey % length;
        while (data[tempPosition] != null) {
            if (data[tempPosition].key == paraKey) {
                return data[tempPosition].content;
            } // Of if
            System.out.println("Not this one for " + paraKey);
            tempPosition = (tempPosition + 1) % length;
        } // Of while

        return "null";
    }// Of hashSearch

    /**
     *********************
     * Test the method.
     *********************
     */
    public static void hashSearchTest() {
        int[] tempUnsortedKeys = { 16, 33, 38, 69, 57, 95, 86 };
        String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
        DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents, 19);

        System.out.println(tempDataArray);

        System.out.println("Search result of 95 is: " + tempDataArray.hashSearch(95));
        System.out.println("Search result of 38 is: " + tempDataArray.hashSearch(38));
        System.out.println("Search result of 57 is: " + tempDataArray.hashSearch(57));
        System.out.println("Search result of 4 is: " + tempDataArray.hashSearch(4));
    }// Of hashSearchTest


//    ----------------------------------------------------
//    ----------------------------------------------------
//    ----------------------------------------------------

    /**
     *********************
     * Insertion sort. data[0] does not store a valid data. data[0].key should
     * be smaller than any valid key.
     *********************
     */
    public void insertionSort() {
        DataNode tempNode;
        int j;
        for (int i = 2; i < length; i++) {
            tempNode = data[i];

            //Find the position to insert.
            //At the same time, move other nodes.
            for (j = i - 1; data[j].key > tempNode.key; j--) {
                data[j + 1] = data[j];
            } // Of for j

            //Insert.
            data[j + 1] = tempNode;

            System.out.println("Round " + (i - 1));
            System.out.println(this);
        } // Of for i
    }// Of insertionSort

    /**
     *********************
     * Test the method.
     *********************
     */
    public static void insertionSortTest() {
        int[] tempUnsortedKeys = { -100, 5, 3, 6, 10, 7, 1, 9 };
        String[] tempContents = { "null", "if", "then", "else", "switch", "case", "for", "while" };
        DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

        System.out.println(tempDataArray);

        tempDataArray.insertionSort();
        System.out.println("Result\r\n" + tempDataArray);



    }// Of insertionSortTest


//    ----------------------------------------------------
//    ----------------------------------------------------
//    ----------------------------------------------------
    /**
     *********************
     * Shell sort. We do not use sentries here because too many of them are needed.
     *********************
     */
    public void shellSort() {
        DataNode tempNode;
        int[] tempJumpArray = { 5, 3, 1 };
        int tempJump;
        int p;
        for (int i = 0; i < tempJumpArray.length; i++) {
            tempJump = tempJumpArray[i];
            for (int j = 0; j < tempJump; j++) {
                for (int k = j + tempJump; k < length; k += tempJump) {
                    tempNode = data[k];
                    // Find the position to insert.
                    // At the same time, move other nodes.
                    for (p = k - tempJump; p >= 0; p -= tempJump) {
                        if (data[p].key > tempNode.key) {
                            data[p + tempJump] = data[p];
                        } else {
                            break;
                        } // Of if
                    } // Of for p

                    // Insert.
                    data[p + tempJump] = tempNode;
                } // Of for k
            } // Of for j
            System.out.println("Round " + i);
            System.out.println(this);
        } // Of for i
    }// Of shellSort



    /**
     *********************
     * Shell sort. We do not use sentries here because too many of them are needed.
     *********************
     */
    public void shellSort1() {
        DataNode tempNode;
        int tempJump;
        int position;
        int i;
        int round=1;

        for (tempJump = length / 2; tempJump >= 1; tempJump = tempJump / 2) {
            for (position = tempJump;  position< length; position += 1) {
                tempNode = data[position];
                // Find the position to insert.
                // At the same time, move other nodes.
                for (i = position - tempJump; i >= 0&&tempNode.key<data[i].key; i -= tempJump) {
                    data[i+tempJump]=data[i];
                } // Of for i
                // Insert.
                data[i + tempJump] = tempNode;
            } // Of for position

            System.out.println("Round " + round);
            System.out.println(this);
            round++;
        }
    }// Of shellSort
    /**
     *********************
     * Test the method.
     *********************
     */
    public static void shellSortTest() {
        int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9, 12, 8, 4 };
        String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while", "throw", "until", "do" };
        DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

        System.out.println(tempDataArray);

        tempDataArray.shellSort1();
        System.out.println("Result\r\n" + tempDataArray);
    }// Of shellSortTest





}// Of class DataArray

五. 数据测试

        原先的代码和修改后的代码都是一样的运行结果:

六. 总结与反思

        这一小节关键思想是理解直接插入算法在①基本有序,②数据量小的前提下,排序效率很高,然后我们根据这两个线索,构造出来先设定大步长然后慢慢减小步长的算法,从而每一次都是对一个基本有序且数据量较小的数组进行排序;这样得到的最终效率是比较高的。这一小节的知识是完全从前面知识剥离出来的;告诉我们关于算法完全可以在前者的基础上更改条件构造出更好的算法。

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

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

相关文章

报名抽奖功能(互动功能接收端JS-SDK)

功能概述 本模块主要处理报名抽奖相关逻辑&#xff0c;如抽奖开始、结束和更新等事件消息。 图&#xff1a;抽奖--效果截图 图&#xff1a;抽奖--效果截图 初始化及销毁 在实例化该模块并进行使用之前&#xff0c;需要对SDK进行初始化配置&#xff0c;详细见参考文档。 在线…

直播教学答题卡(互动功能发起端JS-SDK)

本 SDK 主要包括发起答题卡、管理答题卡题库等功能。以下操作仅支持角色为讲师/嘉宾/助教/管理员的用户执行。 答题卡可以分为快速问答和普通答题卡。 快速问答只有单选和多选两种类型&#xff0c;没有具体的选项内容&#xff0c;最多可有 5 个选项。普通答题卡题目类型包括&a…

MySQL:索引

索引&#xff0c;在MySQL中非常重要。它能提高数据库的性能&#xff0c;不用加内存&#xff0c;不用改程序&#xff0c;不用调sql&#xff0c;只要执行 正确的 create index &#xff0c;查询速度就可能提高成百上千倍。 但是&#xff0c;查询速度的提高是以插入、更新、删除的…

Lora模型训练-koya SS GUi

前提 现在大部分 AI 产品采用的的大模型(dreamboth),但是在产品的训练中也发现了不仅仅需要较大的内存还需要好的 GPU 成本较高,而且模型较大修改只能重新训练不能修改,为了解决这个问题开始推荐 lora 小模型时代.接下来讲解 lora 模型以及使用小模型(lora)的Koya.SS.GUI的流程…

LeetCode-031. 最近最少使用缓存

HashMap扩容&#xff1a;(30条消息) 代码优化 | 如何设置HashMap的初始值大小_hashmap指定初始值大小_死牛胖子的博客-CSDN博客 1、哈希表LinkedList 超出时间&#xff08;&#xff09; Collection(集合):容器,用于存放对象(引用类型。基本类型需要自动装箱) List(列表):元素…

正则表达式(一):基础命令及字符

正则表达式一-基础命令及字符 一、常用命令补充&#xff1a;1.grep&#xff1a;2.sort&#xff1a;3.uniq&#xff1a;快速去重4.tr&#xff1a;5.cut&#xff1a;6.split&#xff1a;文件拆分7.paste&#xff1a;合并文件8.例题应用&#xff1a; 二、正则表达式&#xff1a;1.…

UID和cookie的查找

1、首先在浏览器中输入www.weibo.cn(如图1)&#xff0c; 然后按回车键&#xff0c;打开微博&#xff08;如图2&#xff09;。 图1 图2 2、在上图空白处单击鼠标右键&#xff0c;在显示出的对话框中点击【检查】&#xff0c;如下图。 3、如下图&#xff0c;点击【网络】或者【N…

chatgpt赋能python:Python自定义函数:让编程更高效

Python自定义函数&#xff1a;让编程更高效 Python是一种非常流行的编程语言&#xff0c;它有很多强大的功能&#xff0c;包括自定义函数。Python的自定义函数可以让你编写自己的代码&#xff0c;并将其作为一个函数来使用。这在编程中非常有用&#xff0c;因为它可以让你将代…

java设计模式(十九)备忘录模式

目录 定义模式结构角色职责代码实现适用场景优缺点定义 备忘录模式(Memento Pattern) 保存一个对象的某个状态,以便在适当的时候恢复对象。在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。备忘录模式属于行为型模式。 模式结构 角色职责 …

数据结构04:串的存储结构与KMP算法

前言 参考用书&#xff1a;王道考研《2024年 数据结构考研复习指导》 参考用书配套视频&#xff1a;4.1_1_串的定义和基本操作_哔哩哔哩_bilibili 特别感谢&#xff1a; Google Bard老师[解释KMP&#xff0c;修改BUG]、Chat GPT老师[修改BUG]、BING老师[封面图]~ 当我请求BI…

chatgpt赋能python:Python如何使用空行优化SEO

Python 如何使用空行优化 SEO 在网页排名算法中&#xff0c;空行的使用可以对网页的排名产生影响。在 Python 中&#xff0c;空行的使用也被用来优化代码和提高代码的可读性。本文将介绍如何在 Python 中使用空行来优化代码和优化 SEO。 空行的作用 在 Python 中&#xff0c…

【论文阅读】AlexNet: ImageNet Classification with Deep Convolutional Neural Networks

1. 简介 AlexNet是一个用于图像识别的卷积神经网络&#xff0c;其应用在ILSVRC比赛中&#xff0c;AlexNet所用的数据集是ImageNet&#xff0c;总共识别1000个类别 2. 网络结构 整体网络结果如下图所示&#xff0c;一共有8层&#xff0c;前五层是卷积层&#xff0c;后三层是全…

Kubernetes之pod

Kubernetes之pod 在通过docker运行程序时&#xff0c;我们通常会制作Dockerfile文件构建镜像。也可以基于某个镜像运行容器在容器中安装组件之后&#xff0c;再基于容器生成镜像 使用如下命令可生成镜像&#xff0c;想了解更多参数请添加–help docker build -f Dockerfile路…

(超超详!!)Linux进程间通信-----管道 + 共享内存详解

索引 通信背景管道匿名管道命名管道 共享内存基本概念共享内存如何管理共享内存的相关函数共享内存的删除共享内存的使用 通信背景 进程是具有独立性的,每个进程都有独立的PCB,独立的数据和数据结构,因此进程间想要交互数据,成本会非常高,但有时候需要多进程协同处理同一件事情…

java设计模式(十五)责任链模式

目录 定义模式结构角色职责代码实现适用场景优缺点 定义 责任链模式(Chain of Responsibility) 使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有对象能够处理…

deque介绍

目录 简介&#xff1a; 初识deque deque的底层实现 deque插入 deque的operator[] deque的迭代器 deque的缺陷 与vector比的缺陷 与list相比的缺陷 deque的优势 简介&#xff1a; 这一节不会进行模拟实现&#xff0c;只会聊聊deque的底层 原因是我们学习deque是为了…

RabbitMQ中的AMQP协议与核心组成介绍

前言 在RabbitMQ中为了传输数据&#xff0c;使用的是基于TCP/IP协议构造的AMQP协议。RabbitMQ的核心组成部分包括&#xff1a;Server、Connection、Channel、Message、ExChange、Virtual Host、Bingings、Routing key、Queue AMQP协议 AMQP协议全称&#xff1a;Advanced Mes…

RK3588平台开发系列讲解(驱动基础篇)信号驱动 IO 实验

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、信号驱动 IO 简介二、实验程序2.1、应用程序2.2、驱动程序沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 信号驱动 IO 不需要应用程序查询设备的状态,一旦设备准备就绪,会触发 SIGIO 信号,进而调用注…

论文中文翻译——kAFL Hardware-Assisted Feedback Fuzzing for OS Kernels

本论文相关内容 论文下载地址——26th USENIX Security Symposium论文中文翻译——kAFL Hardware-Assisted Feedback Fuzzing for OS Kernels 文章目录 本论文相关内容前言kAFL&#xff1a;操作系统内核的硬件辅助反馈Fuzzing作者信息论文来源主办方信息摘要1 引言2 技术背景2…

系统U盘制作随记

随身系统U盘制作 最近花了好多时间&#xff0c;废了好多U盘才把这东西搞明白了。 主要是自己的笔记本问题比较多&#xff0c;用实验室的Hp机一下就弄好了。 用这篇博客总结一下自己&#xff0c;然后附上详细的流程以免大家踩坑。 Windows to Go 这个比较容易上手 1. 准备…