Day_49归并排序

news2025/2/12 13:58:20

目录

一. 归并排序的思想

        1.归并排序的过程

        2. 两种实现方式:

        2.1 非递归实现方式

        2.2递归实现方式

二. 归并排序的代码实现

        1. 数组的辅助空间及初始化

        2. 核心代码

        2.1每个小组的基本设置

        2.2小组内部的排序

三. 代码展示

四. 运行结果

五. 总结


一. 归并排序的思想

        1.归并排序的过程

        归并排序与之前学习的基于交换、选择等排序的思想不一样,“归并”的含义是将两个或者两个以上的有序表合并成一个新的有序表。假定排序表含有n个记录,则可将其视为n个有序的子表,每个子表的长度为1,然后两两归并,得到n/2个长度为2或1的有序表;继续两两归并......如此重复,直到合成一个长度为n的有序表为止,这种排序方法称为2路归并。

2路归并排序示例

        2. 两种实现方式:

        2.1 非递归实现方式

        由于还可以直接设置变量的方式,直接实现排序(没有递归,这里可以类比树的先序遍历——递归和非递归两种实现方式),只不过这里就是将数组直接分成小块,然后排序,最后直接组合,没有递归排序那种向下分的过程。

        2.2递归实现方式

        这里的递归实现方式十分简单,类似于快速排序里面的分治思想,将一个数组序列分成一半然后再次调用自身函数,再将这个数组序列的一半再分为一半,直到达到临界条件,最后将这些分散的数字序列合并起来。

二. 归并排序的代码实现

        1. 数组的辅助空间及初始化

        tempRow:用来控制现在进行到哪个小组(1,2,3,4...)

        tempGroups:小组的个数

        tempNextRow,tempNextRow:当前使用的哪个辅助数组

        tempGroupNumber:遍历循环tempGroups

        tempFirstStart, tempSecondStart, tempSecondEnd:同一个小组内第一个序列应该开始的位置,第二个序列应该开始的位置,第二个序列结束的位置(由于第一个序列结束的位置是第二个序列开始位置减一,故不设置tempFirstStartEnd)

        tempFirstIndex, tempSecondIndex:相当于遍历完同一个小组内的临时变量

        tempNumCopied:控制复制到辅助空间的数

        这一段代码基本上是初始化,接着构建辅助空间1,辅助空间2,将原本的数组序列复制到辅助空间1。

        // Step 1. Allocate space.

        int tempRow; // The current row
        int tempGroups; // Number of groups
        int tempActualRow; // Only 0 or 1
        int tempNextRow = 0;
        int tempGroupNumber;
        int tempFirstStart, tempSecondStart, tempSecondEnd;
        int tempFirstIndex, tempSecondIndex;
        int tempNumCopied;
        for (int i = 0; i < length; i++) {
            System.out.print(data[i]);
        } // Of for i
        System.out.println();

        DataNode[][] tempMatrix = new DataNode[2][length];

        // Step 2. Copy data.
        for (int i = 0; i < length; i++) {
            tempMatrix[0][i] = data[i];
        } // Of for i

        2. 核心代码

        2.1每个小组的基本设置

        这里首先引入tempSize控制数字序列的分组(1,2,4,8...);现在进行到第tempRow号组;tempActualRow,tempNextRow表示现在的辅助空间;接着计算小组的个数(在tempSize的情况下)

        tempRow = -1;
        for (int tempSize = 1; tempSize <= length; tempSize *= 2) {
            // Reuse the space of the two rows.
            tempRow++;
            System.out.println("Current row = " + tempRow);
            tempActualRow = tempRow % 2;
            tempNextRow = (tempRow + 1) % 2;

            tempGroups = length / (tempSize * 2);
            if (length % (tempSize * 2) != 0) {
                tempGroups++;
            } // Of if
            System.out.println("tempSize = " + tempSize + ", numGroups = " + tempGroups);

        2.2小组内部的排序

        tempGroupNumber记录现在排到第几号小组,tempFirstStart记录当前小组的第一个序列的开始位,tempSecondStart记录当前小组的第二个序列的开始位;这里判断tempSecondStart是否越界,若越界说明这个小组只有第一个数字序列,直接复制到辅助空间;tempSecondEnd记录同一个小组的结束位。

        记录完成开始位置和结束位置,对同一个小组的数据进行排序,若第一个序列的tempFirstIndex位置数据≤第二个序列tempSecondIndex位置数据,复制tempFirstIndex位置数据到辅助空间,同样当tempFirstIndex位置数据>第二个序列tempSecondIndex位置数据,复制tempSecondIndex位置数据到辅助空间,直到一方计算完毕,将另一方的所有数据复制到辅助空间。

        最终for (int tempSize = 1; tempSize <= length; tempSize *= 2) 循环结束,排序完成。

            for (tempGroupNumber = 0; tempGroupNumber < tempGroups; tempGroupNumber++) {
                tempFirstStart = tempGroupNumber * tempSize * 2;
                tempSecondStart = tempGroupNumber * tempSize * 2 + tempSize;
                if (tempSecondStart > length - 1) {
                    // Copy the first part.
                    for (int i = tempFirstStart; i < length; i++) {
                        tempMatrix[tempNextRow][i] = tempMatrix[tempActualRow][i];
                    } // Of for i
                    continue;
                } // Of if
                tempSecondEnd = tempGroupNumber * tempSize * 2 + tempSize * 2 - 1;
                if (tempSecondEnd > length - 1) {
                    tempSecondEnd = length - 1;
                } // Of if

                System.out
                        .println("Trying to merge [" + tempFirstStart + ", " + (tempSecondStart - 1)
                                + "] with [" + tempSecondStart + ", " + tempSecondEnd + "]");

                tempFirstIndex = tempFirstStart;
                tempSecondIndex = tempSecondStart;
                tempNumCopied = 0;
                while ((tempFirstIndex <= tempSecondStart - 1)
                        && (tempSecondIndex <= tempSecondEnd)) {
                    if (tempMatrix[tempActualRow][tempFirstIndex].key <= tempMatrix[tempActualRow][tempSecondIndex].key) {

                        tempMatrix[tempNextRow][tempFirstStart
                                + tempNumCopied] = tempMatrix[tempActualRow][tempFirstIndex];
                        tempFirstIndex++;
                        System.out.println("copying " + tempMatrix[tempActualRow][tempFirstIndex]);
                    } else {
                        tempMatrix[tempNextRow][tempFirstStart
                                + tempNumCopied] = tempMatrix[tempActualRow][tempSecondIndex];
                        System.out.println("copying " + tempMatrix[tempActualRow][tempSecondIndex]);
                        tempSecondIndex++;
                    } // Of if
                    tempNumCopied++;
                } // Of while

                while (tempFirstIndex <= tempSecondStart - 1) {
                    tempMatrix[tempNextRow][tempFirstStart
                            + tempNumCopied] = tempMatrix[tempActualRow][tempFirstIndex];
                    tempFirstIndex++;
                    tempNumCopied++;
                } // Of while

                while (tempSecondIndex <= tempSecondEnd) {
                    tempMatrix[tempNextRow][tempFirstStart
                            + tempNumCopied] = tempMatrix[tempActualRow][tempSecondIndex];
                    tempSecondIndex++;
                    tempNumCopied++;
                } // Of while
            } // Of for groupNumber

三. 代码展示

        主类:

package Day_49;


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"};
//        System.out.println(paraKeyArray.length);
        DataArray test=new DataArray(paraKeyArray,paraContentArray);

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


    }// Of main
}

        调用类:

package Day_49;

/**
 * Data array for searching and sorting algorithms.
 *
 * @author Fan Min minfanphd@163.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 entrance of the program.
     *
     * @param args Not used now.
     *********************
     */
    public static void main(String args[]) {
        System.out.println("\r\n-------sequentialSearchTest-------");
        sequentialSearchTest();

        System.out.println("\r\n-------binarySearchTest-------");
        binarySearchTest();
    }// Of main
//-------------------------------------------
    /**
     *********************
     * Merge sort. Results are stored in the member variable data.
     *********************
     */
    public void mergeSort() {
        // Step 1. Allocate space.

        int tempRow; // The current row
        int tempGroups; // Number of groups
        int tempActualRow; // Only 0 or 1
        int tempNextRow = 0;
        int tempGroupNumber;
        int tempFirstStart, tempSecondStart, tempSecondEnd;
        int tempFirstIndex, tempSecondIndex;
        int tempNumCopied;
        for (int i = 0; i < length; i++) {
            System.out.print(data[i]);
        } // Of for i
        System.out.println();

        DataNode[][] tempMatrix = new DataNode[2][length];

        // Step 2. Copy data.
        for (int i = 0; i < length; i++) {
            tempMatrix[0][i] = data[i];
        } // Of for i

        // Step 3. Merge. log n rounds
        tempRow = -1;
        for (int tempSize = 1; tempSize <= length; tempSize *= 2) {
            // Reuse the space of the two rows.
            tempRow++;
            System.out.println("Current row = " + tempRow);
            tempActualRow = tempRow % 2;
            tempNextRow = (tempRow + 1) % 2;

            tempGroups = length / (tempSize * 2);
            if (length % (tempSize * 2) != 0) {
                tempGroups++;
            } // Of if
            System.out.println("tempSize = " + tempSize + ", numGroups = " + tempGroups);

            for (tempGroupNumber = 0; tempGroupNumber < tempGroups; tempGroupNumber++) {
                tempFirstStart = tempGroupNumber * tempSize * 2;
                tempSecondStart = tempGroupNumber * tempSize * 2 + tempSize;
                if (tempSecondStart > length - 1) {
                    // Copy the first part.
                    for (int i = tempFirstStart; i < length; i++) {
                        tempMatrix[tempNextRow][i] = tempMatrix[tempActualRow][i];
                    } // Of for i
                    continue;
                } // Of if
                tempSecondEnd = tempGroupNumber * tempSize * 2 + tempSize * 2 - 1;
                if (tempSecondEnd > length - 1) {
                    tempSecondEnd = length - 1;
                } // Of if

                System.out.println("Trying to merge [" + tempFirstStart + ", " + (tempSecondStart - 1)
                                + "] with [" + tempSecondStart + ", " + tempSecondEnd + "]");

                tempFirstIndex = tempFirstStart;
                tempSecondIndex = tempSecondStart;
                tempNumCopied = 0;
                while ((tempFirstIndex <= tempSecondStart - 1)
                        && (tempSecondIndex <= tempSecondEnd)) {
                    if (tempMatrix[tempActualRow][tempFirstIndex].key <= tempMatrix[tempActualRow][tempSecondIndex].key) {

                        tempMatrix[tempNextRow][tempFirstStart
                                + tempNumCopied] = tempMatrix[tempActualRow][tempFirstIndex];
                        tempFirstIndex++;
                        System.out.println("copying " + tempMatrix[tempActualRow][tempFirstIndex]);
                    } else {
                        tempMatrix[tempNextRow][tempFirstStart
                                + tempNumCopied] = tempMatrix[tempActualRow][tempSecondIndex];
                        System.out.println("copying " + tempMatrix[tempActualRow][tempSecondIndex]);
                        tempSecondIndex++;
                    } // Of if
                    tempNumCopied++;
                } // Of while

                while (tempFirstIndex <= tempSecondStart - 1) {
                    tempMatrix[tempNextRow][tempFirstStart
                            + tempNumCopied] = tempMatrix[tempActualRow][tempFirstIndex];
                    tempFirstIndex++;
                    tempNumCopied++;
                } // Of while

                while (tempSecondIndex <= tempSecondEnd) {
                    tempMatrix[tempNextRow][tempFirstStart
                            + tempNumCopied] = tempMatrix[tempActualRow][tempSecondIndex];
                    tempSecondIndex++;
                    tempNumCopied++;
                } // Of while
            } // Of for groupNumber

            System.out.println("Round " + tempRow);
            for (int i = 0; i < length; i++) {
                System.out.print(tempMatrix[tempNextRow][i] + " ");
            } // Of for j
            System.out.println();
        } // Of for tempStepSize

        data = tempMatrix[tempNextRow];
    }// Of mergeSort

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

        System.out.println(tempDataArray);

        tempDataArray.mergeSort();
        System.out.println(tempDataArray);
    }// Of mergeSortTest

}// Of class DataArray

四. 运行结果

        

五. 总结

        这部分代码变量相当多,虽然多,但是必须弄懂每个变量指代的含义,至于一个变量的含义首先可以根据闵来师变量的名字来理解,其次归并排序的过程一定要理解;只有这两者同时具备才是看懂这部分代码的第一步(这里举个例子tempSize这个变量是在每次循环乘2,那么总共它就循环logn次,这不就是归并的分治深度吗?所以我才将tempSize理解为归并循环的次数)。其次这里的代码不像递归排序的代码,递归排序的代码很简单,就几行,它没有许多的变量,只是反复调用自身即可。

        总而言之,这部分代码我个人的看法是①首先把归并排序思想过程要理解到位,②用人脑模拟计算机运行代码的过程,③闵老师的代码名字要好好理解。这样这部分代码就可以解决了。

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

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

相关文章

Android逆向环境搭建

逆向工具 手机root Android逆向必要条件是你需要有个Root的手机&#xff0c;最好是真机。没有root的手机&#xff0c;逆向工作很难继续下去&#xff0c;手机的话&#xff0c;能解锁OEM的都可以。手机Root的话一般有以下几步&#xff1a; 解锁OEM解锁BootLoader安装Magisk制作…

Win11的两个实用技巧系列之夜间模式怎么定时、如何卸载重装应用商店?

Win11如何卸载重装应用商店? Win11删除重装Microsoft Store的命令 Win11如何卸载重装应用商店&#xff1f;Win11中的应用商店想要卸了重装&#xff0c;该怎么操作呢&#xff1f;下面我们就来看看Win11删除重装Microsoft Store的命令 Microsoft Store也就是微软的应用商店&…

Redis的主从复制和哨兵机制详解

目录 一、CAP 原理二、Redis主从同步1、主从同步是什么能干嘛&#xff1f;2、Redis是如何实现数据同步的&#xff1f;2.1.增量同步2.2.快照同步2.3.无盘复制2.4.通过Wait 指令保证强一致性 3、搭建Redis 1主2从3.1.安装Redis3.2.创建1主2从配置文件3.3.启动Redis3.4.验证主从同…

算法分析和大O简介

在本文中&#xff0c;我们将讨论如何分析算法以及为什么这样做很重要&#xff01; 为什么要分析算法&#xff1f; 在我们开始之前&#xff0c;让我们澄清一下什么是算法。在本文中&#xff0c;算法只是解决问题的过程或公式。有些问题非常有名&#xff0c;以至于算法都有名字…

JMeter参数化4种实现方式

目录 前言&#xff1a; 1 参数化释义 2 参数化实现 CSV实例 注意事项 前言&#xff1a; 在使用JMeter进行测试时&#xff0c;参数化允许您模拟不同的用户、不同的数据、不同的操作等&#xff0c;从而增加了测试的灵活性和复用性 1 参数化释义 什么是参数化&#xff1f;…

软件系统开发包括哪些步骤?

在传统的理解中&#xff0c;企业内数字化应用的开发和迭代应该是 IT 部门的工作&#xff0c;但事实并非如此。一方面&#xff0c;激烈的市场竞争和反复出现的疫情给数字化提出了新的要求&#xff1b;另一方面&#xff0c;五花八门的零代码、低代码工具正如雨后春笋一般出现&…

NB-lot和LoRa真正的差别在哪里?

就像要把大象装冰箱一样&#xff0c;物联网&#xff0c;万物互联也是要分步骤的。 一、感知层(信息获取层)&#xff0c;即利用各种传感器等设备随时随地获取物体的信息; 二、网络层(信息传输层)&#xff0c;通过各种电信网络与互联网的融合&#xff0c;将物体的信息实时准确地…

[AI语音克隆] 5秒内克隆您的声音并生成任意语音内容

前言 随着人工智能技术的不断发展&#xff0c;语音克隆技术也得到了越来越多的关注和研究。目前&#xff0c;AI语音克隆技术已经可以实现让机器模拟出一个人的声音&#xff0c;甚至可以让机器模拟出一个人的语言习惯和表情。 然而&#xff0c;AI语音克隆技术仍然面临着许多难…

BB84协议:量子秘钥分发

文章目录 为什么需要量子密钥分发通讯工具基本通讯 BB84协议为什么这样做能防止通讯被窃听?在传统信道上的窃听在量子信道上的窃听 内容来源&#xff1a; 为什么需要量子密钥分发 BB84协议是一种“密钥分发协议”&#xff0c;所以从功能上来讲&#xff0c;它要实现的目标与之…

618大促 | 解析平台、商家和消费者必须面对的三大风险

目录 618年中大促的三大风险 商家乐此不疲的“刷单炒信” 消费者无计可施的“薅羊毛” 平台恨之入骨的“恶意爬虫” 618三类欺诈风险的特点 618电商平台的业务安全防控之道 618大促再次开启&#xff0c;各平台及商家的促销大战如火如荼。 2023年618&#xff0c;京东推出…

【状态估计】用于非标量系统估计的最优卡尔曼滤波(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

leetcode数据结构题解(Java实现,第一天和第二天)

文章目录 第一天217. 存在重复元素53.最大子数组和 第二天1. 两数之和88. 合并两个有序数组 第一天 217. 存在重复元素 题解思路&#xff1a;首先题目需要的是判断数组中是否存在相同的数字&#xff0c;存在返回true,不存在就返回false。 那么显然可以这样做&#xff0c;先进行…

内网IM即时通讯软件WorkPlus,快速连接工作的沟通利器

在当今信息高度发达的时代&#xff0c;企业内部沟通的重要性不言而喻。随着企业团队的扩大和分布式办公的兴起&#xff0c;即时通讯软件成为了一种必不可少的工具。通过即时通讯软件&#xff0c;团队成员可以实时交流和协作&#xff0c;快速解决问题&#xff0c;加快决策过程。…

Echarts的地图实现拖拽缩放同步功能(解决多层geo缩放、拖动卡顿问题)

项目场景&#xff1a; 大屏项目显示云南省3D的地图&#xff0c;可拖拽缩放、地图打点、点击图标弹框等等功能 问题描述 多图层拖拽时会上下层会分离&#xff0c;延迟卡顿 原因分析&#xff1a; 1、拖拽时不同图层的中心坐标没有保持一致&#xff0c; 2、卡顿是数据更新动画时…

玩业余无线电时,突然听到有人呼救,该怎么办?

不管是在玩业余无线电还是在其他活动当中&#xff0c;突然遇到有人求救&#xff0c;都是一件非常重要的事情&#xff0c;因为救援行动的效率快慢和是否及时&#xff0c;都有可能影响到别人的生命安全。 下面是河南宝蓝小编给出的一些思考和建议&#xff0c;希望对大家会有一些帮…

软件测试-测试用例

目录 测试用例的四个要素 测试用例设计方法 基于需求进行测试用例的设计 等价类 边界值 判定表 正交表 通过allpirs画正交表 场景设计法 错误猜测法 面试题 如何模拟弱网 接口如何测试 zip命令测试 测试用例万能公式 水杯测试用例 微信发朋友圈 测试用例的四个…

Java实现的五子棋游戏 ~java.awtjava.swing

文章目录 Java实现的五子棋游戏1.实现效果2.实现源码2.1运行主函数main.java2.2 棋盘布局Chessboard.java3.Algorithm算法 点击下载链接&#xff1a;Java实现的五子棋游戏源码下载 Java实现的五子棋游戏 作业要求&#xff1a; &#xff08;1&#xff09;课题代号&#xff1a; …

老Mac电脑安装macOS Ventura实战

前提说明&#xff1a;此实战适用于老旧Mac电脑&#xff08;2015年之前的&#xff0c;无法在系统设置中升级macOS Ventura系统的电脑&#xff09;安装macOS Ventura系统&#xff01; 软件&#xff1a;OpenCore-Patcher-GUI.app.zip 工具&#xff1a;16G U盘、或者移动硬盘&a…

Spring MVC拦截器Interceptor使用(判断用户登录)

文章目录 一 概念二 3步使用三 HandlerInterceptor接口四 代码实现 一 概念 Spring MVC中的拦截器&#xff08;Interceptor&#xff09;类似于Servlet中的过滤器&#xff08;Filter&#xff09;&#xff0c;它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验…

superset链接本地数据库

打开图中 选择database 先解释SQLlite的格式 如下 SQLALCHEMY_DATABASE_URI mysql://username:password127.0.0.1:3306/gmall_report’ 请将 username 和 password 替换为实际的 MySQL 数据库的用户名和密码。 mysql则为如下