Java数据结构(十)——冒泡排序、快速排序

news2024/11/25 16:30:10

文章目录

  • 冒泡排序
    • 算法介绍
    • 代码实现
    • 优化策略
    • 复杂度和稳定性
  • 快速排序
    • 算法介绍
    • 优化策略
    • 非递归实现
    • 代码演示
    • 复杂度和稳定性

冒泡排序

算法介绍

冒泡排序是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就交换。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,就像冒泡一样。

冒泡排序算法的步骤如下(排升序):

  1. 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数;
  3. 针对所有的元素重复以上的步骤,除了最后每轮筛选出来的最大的值;
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

【图示】

在这里插入图片描述


代码实现

    public void bubbleSort(int[] array) {
        int len = array.length;
        while(len > 0) {
            len--;
            for(int i = 0; i < len; i++) {
                if(array[i] > array[i+1]) {
                    int tmp = array[i];
                    array[i] = array[i+1];
                    array[i+1] = tmp;
                }
            }
        }
    }

优化策略

上代码存在一个问题可以优化,这个问题是:当某次遍历交换完后序列有序,排序不会停止,而是继续走完所有的趟数。对此可以优化,使得在某趟遍历没有任何交换的情况下(已经有序),不再开始下一趟,直接跳出排序,代码如下:

    public void bubbleSort() {
        int len = array.length;
        boolean flag = true;
        while(len > 0 && flag) {
            len--;
            flag = false;
            for(int i = 0; i < len; i++) {
                if(array[i] > array[i+1]) {
                    flag = true;
                    int tmp = array[i];
                    array[i] = array[i+1];
                    array[i+1] = tmp;
                }
            }
        }
    }

优化代码中通过设置了一个boolean类型的变量,保证了当序列有序,能够及时结束排序。


复杂度和稳定性

时间复杂度O(N^2)

优化后的冒泡排序在第一次遍历且没有交换发生时就会停止,因此某些时候时间复杂度可以从O(N^2)降低到O(N)。虽然优化后的冒泡排序在最好情况下有显著改进,但在最坏情况和平均情况下的时间复杂度并没有改变,仍为O(N^2)

空间复杂度O(1)

稳定性:稳定,通过控制交换的条件(相等时不交换)可以达到稳定。


快速排序

算法介绍

快速排序是一种高效的排序算法。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

快速排序使用 分治法策略 来把一个序列分为较小和较大的两个子序列,然后递归地排序两个子序列。

(排升序)将序列划分为两个序列需要确定一个基准值,当划分结束后,基准值左边元素均小于该基准值,右边元素均大于该基准值。 实现这种划分有三种方式,分别是:挖坑法Hoare法前后指针法

【挖坑法】

首先确定一个基准值,通常会选择序列最左边的元素,然后将基准值存放在key变量中(通常将存放基准值的变量命名为key),此时将基准值所在位置视为“坑”。需要其他元素来“填坑”,由于基准值是序列的最左边的元素,所以我们要从序列的最右端开始,向前寻找第一个比基准值小的元素作为填坑元素填到坑位,之后,坑位更新到填坑元素的位置,由于填坑元素是从右边开始寻找的,所以我们要从左边开始寻找第一个比基准值大的元素作为填坑元素填坑,更新坑位到填坑元素的位置,继续第二轮,接着上次右边的位置向左寻找第一个比基准值小的元素填坑……以此类推,当向右寻找和向左寻找的两个位置重合,结束循环,重合位置就是基准值应所在的位置,此时基准值左边的所有元素都小于基准值,基准值右边的所有元素都大于基准值,即确定了基准值的最终位置。

图示:

在这里插入图片描述

关键代码实现

        int key = array[0];//存放基准值
        int pivot = 0;//坑位(下标值)
        int left = 0;//左“指针”(下标值)
        int right = array.length - 1;//右“指针”(下标值)
        while(left < right) {
            while(left < right && array[right] >= key) {
                right--;
            }
            array[pivot] = array[right];
            pivot = right;
            while(left < right && array[left] <= key) {
                left++;
            }
            array[pivot] = array[left];
            pivot = left;
        }
        array[pivot] = key;
  • 注意问题
    1. 左右“指针”寻找填坑元素时,要注意判断left < right,避免寻找过程中超出寻找范围
    2. 当 right 向前(left 向后)寻找比 key 值小(大)的元素时,对于遇到与 key 值相同值得处理,应该不是目标值,要跳过继续寻找。

【Hoare法】

首先选定一个基准值(通常最左边),创建两个“指针”,分别指向最左边和最右边,右指针从右向左移动时,它会寻找第一个小于基准值的元素;左指针开始从左向右移动,寻找第一个大于基准值的元素,找到后,进行交换;重复寻找并交换的过程,直到左右“指针”相遇;最后,将基准值与相遇的位置的元素交换。

在这里插入图片描述

关键代码实现

        int key = array[0];
        int left = 0;
        int right = array.length - 1;
        while(left < right) {
            while(left < right && array[right] >= key) {
                right--;
            }
            while(left < right && array[left] <= key) {
                left++;
            }
            swap(array, left, right);
        }
        swap(array, 0, left);
  • 注意问题
    1. 先动右指针,再动左指针
    2. 指针寻找时找到与基准值一样的值,跳过继续寻找,即取等号

【前后指针法】

选定最左边元素为基准值,创建两个指针,这里命名为prevcur,初始分别指向基准值位置和基准值下一个位置,cur负责向后寻找比基准值小的元素,找到了就让prev++然后交换两个指针指向的位置的元素,然后继续寻找交换,直到cur指针越界,最后,将prev指向的位置的元素与基准值元素交换。

在这里插入图片描述

关键代码实现

        int key = array[0];
        int cur = 1;
        int prev = 0;
        while(cur < array.length) {
            if(array[cur] < key && array[++prev] != array[cur]) {
                swap(array, cur, prev);
            }
            cur++;
        }
        swap(array, 0, prev);

演示三种划分方法使用的元素序列是一致的,但最终划分的结果可能不同:

  • 挖坑法:[15, 29, 29, 34, 87, 45, 63, 56, 78, 71]
  • Hoare法:[29, 15, 29, 34, 87, 45, 63, 56, 78, 71]
  • 前后指针法:[15, 29, 29, 34, 87, 45, 63, 56, 78, 71]

但即使划分的结果不同,最终都能满足基准值的位置是正确的,且其左边元素均比它小,右边的元素均比它大


三种划分方式的使用频率和重要程度即介绍的顺序:挖坑法 > Hoare法 > 前后指针法。

例如,有些快速排序的选择题会考察第n趟的结果,题目一般都是以挖坑法划分方式的,但如果利用挖坑法得到的结果不在选项中,则依次按照Hoare法和前后指针法尝试。


了解了划分方法后实际上只解决了快速排序的一步,每次经过划分后,都会有一个元素的最终位置确定,并且将序列被分为两个子序列,快速排序要做的是继续对左右子序列进行相同的划分,直到序列有序。可以以递归的方式实现:

【图示】

以挖坑法演示:

在这里插入图片描述


完整实现

    public void quickSort(int[] array, int begin, int end) {
        if(begin >= end) {
            return;
        }
        int key = array[begin];
        int left = begin;
        int right = end;
        int pivot = begin;
        while(left < right) {
            while(left < right && array[right] >= key) {
                right--;
            }
            array[pivot] = array[right];
            pivot = right;

            while(left < right && array[left] <= key) {
                left++;
            }
            array[pivot] = array[left];
            pivot = left;
        }
        array[pivot] = key;
        //递归地划分
        quickSort(array, begin, pivot - 1);
        quickSort(array, pivot + 1, end);
    }

我们假设每次划分后确定的基准值元素的最终位置都在序列的中间位置,于是通过下面的简单图可以理解快速排序的时间复杂度:

在这里插入图片描述

快速排序的平均时间复杂度是O(N*log2N),但这建立在 每次划分后确定的基准值元素的最终位置都在序列的中间位置 的前提下,如果出现极端情况每次每次划分后确定的基准值元素的最终位置都在序列的两侧(即序列有序),此时就会出现快速排序的最坏时间复杂度:O(N^2)的情况。


优化策略

【三数取中】

当序列有序时,快速排序的时间复杂度会达到O(N^2)级别,这是因为有序序列每次拿到的基准值都是序列的最值元素(最大值或最小值),这时候指针就得遍历整个序列。

为此,可以通过三数取中的方式来避免每次确定基准值时选到最值元素,三数取中的原理是:取出序列中位置最左、最右和中间的三个元素,比较它们的大小,选出第二大(即中间大)的元素,然后将它换到基准值位置(通常是最左边),这样取基准值时,就不会出现选到最值的极端情况了

以下是三数取中以及三数取中优化后的快速排序:

    private void swap(int[] array, int a, int b) {
        int tmp = array[a];
        array[a] = array[b];
        array[b] = tmp;
    }

    //三数取中
    private int getMidIndex(int[] array, int left, int right) {
        int mid = left + (right - left >> 1);
        if(array[left] > array[right]) {
            if(array[left] > array[mid]) {
                return array[mid] > array[right] ? mid : right;
            }else {
                return left;
            }
        }else {
            if(array[right] > array[mid]) {
                return array[mid] > array[left] ? mid : left;
            }else {
                return right;
            }
        }
    }

    //三数取中后的快速排序
    public void quickSort(int[] array, int begin, int end) {
        if(begin >= end) {
            return;
        }
        //取得中间大的元素的下标
        int midIndex = getMidIndex(array, begin, end);
        //交换,避免出现极端情况
        swap(array, begin, midIndex);
        int key = array[begin];
        int left = begin;
        int right = end;
        int pivot = begin;
        while(left < right) {
            while(left < right && array[right] >= key) {
                right--;
            }
            array[pivot] = array[right];
            pivot = right;

            while(left < right && array[left] <= key) {
                left++;
            }
            array[pivot] = array[left];
            pivot = left;
        }
        array[pivot] = key;
        //递归地划分
        quickSort(begin, pivot - 1);
        quickSort(pivot + 1, end);
    }

【小区间优化】

对快速排序进行了三数取中优化后,实际上还能继续优化。

小区间优化针对当待排序的数组的数据量较少时,采用其他排序方法(通常是直接插入排序)对小数组排序。因为对大量小数组进行递归调用和分区操作会产生较大的开销。

小区间优化需要确定一个阈值,这个阈值决定了小数组的长度到达多少时进行直接插入排序,阈值的确定与数据量有很大的关系,不过常见的阈值有8,10,15

小区间优化后的快速排序(采用10为阈值,仅作为代码演示):

    private void swap(int[] array, int a, int b) {
        int tmp = array[a];
        array[a] = array[b];
        array[b] = tmp;
    }

    private int getMidIndex(int left, int right) {
        int mid = left + (right - left >> 1);
        if(array[left] > array[right]) {
            if(array[left] > array[mid]) {
                return array[mid] > array[right] ? mid : right;
            }else {
                return left;
            }
        }else {
            if(array[right] > array[mid]) {
                return array[mid] > array[left] ? mid : left;
            }else {
                return right;
            }
        }
    }

    //小区间优化的直接插入排序代码
    public void insertSort(int[] array, int begin, int end) {
        for(int i = begin + 1; i <= end; i++) {
            int tmp = array[i];
            int pos = i - 1;
            for(int j = i - 1; j >= begin; j--) {
                if(array[j] > tmp) {
                    array[j+1] = array[j];
                    pos--;
                }else {
                    break;
                }
            }
            array[pos+1] = tmp;
        }
    }
    public void quickSort(int begin, int end) {
        if(begin >= end) {
            return;
        }
        int midIndex = getMidIndex(begin, end);
        swap(array, begin, midIndex);
        int key = array[begin];
        int left = begin;
        int right = end;
        int pivot = begin;
        while(left < right) {
            while(left < right && array[right] >= key) {
                right--;
            }
            array[pivot] = array[right];
            pivot = right;

            while(left < right && array[left] <= key) {
                left++;
            }
            array[pivot] = array[left];
            pivot = left;
        }
        array[pivot] = key;
        //小区间优化
        if(pivot - 1 - begin <= 10) {
            insertSort(array, begin, pivot - 1);
        }else {
            quickSort(begin, pivot - 1);
        }
        if(end - pivot - 1 <= 10) {
            insertSort(array, pivot + 1, end);
        }else {
            quickSort(pivot + 1, end);
        }
    }

非递归实现

非递归实现需要用到,栈用来存储序列的左右边界下标,需要注意的是:

  • 基于栈的“先入后出”特性,为了能先划分左子序列,我们必须先将右子序列的两个边界下标入栈,再将左子序列的两个边界下标入栈,以确保出栈时先拿到的是左子序列的边界下标
  • 向栈中存放某个序列的两个边界下标时,也要注意栈的特性,比如,接下来的示例代码中,我们选择先将右边界下标入栈,再将左边界下标入栈
    public void quickSortNoR(int[] array) {
        //创建一个栈,并初始化栈的元素
        Stack<Integer> stack = new Stack<>();
        stack.push(array.length - 1);
        stack.push(0);
        //快速排序的核心代码
        while(!stack.isEmpty()) {
            //出栈,注意出栈元素的含义,要结合入栈顺序
            int begin = stack.pop();
            int end = stack.pop();
            int key = array[begin];
            int left = begin;
            int right = end;
            int pivot = begin;
            while(left < right) {
                while(left < right && array[right] >= key) {
                    right--;
                }
                array[pivot] = array[right];
                pivot = right;

                while(left < right && array[left] <= key) {
                    left++;
                }
                array[pivot] = array[left];
                pivot = left;
            }
            array[pivot] = key;
            //入栈,入栈规则:先入右子序列的两个边界,再入左子序列的两个边界
            if(end - pivot - 1 > 1) {
                stack.push(end);
                stack.push(pivot + 1);
            }
            if(pivot - 1 - begin > 1) {
                stack.push(pivot - 1);
                stack.push(begin);
            }
        }
    }

演示代码并没有采用三数取中和小区间优化,读者可以自行尝试,也比较简单,理解了非递归代码后在合适的位置插入优化代码即可。


代码演示

方便起见,将代码再次展示:

递归实现(三数取中和小区间优化)

    public void quickSort(int begin, int end) {
        if(begin >= end) {
            return;
        }
        int midIndex = getMidIndex(begin, end);
        swap(array, begin, midIndex);
        int key = array[begin];
        int left = begin;
        int right = end;
        int pivot = begin;
        while(left < right) {
            while(left < right && array[right] >= key) {
                right--;
            }
            array[pivot] = array[right];
            pivot = right;

            while(left < right && array[left] <= key) {
                left++;
            }
            array[pivot] = array[left];
            pivot = left;
        }
        array[pivot] = key;
        //小区间优化
        if(pivot - 1 - begin <= 10) {
            insertSort(array, begin, pivot - 1);
        }else {
            quickSort(begin, pivot - 1);
        }
        if(end - pivot - 1 <= 10) {
            insertSort(array, pivot + 1, end);
        }else {
            quickSort(pivot + 1, end);
        }
    }

    private void swap(int[] array, int a, int b) {
        int tmp = array[a];
        array[a] = array[b];
        array[b] = tmp;
    }

    private int getMidIndex(int left, int right) {
        int mid = left + (right - left >> 1);
        if(array[left] > array[right]) {
            if(array[left] > array[mid]) {
                return array[mid] > array[right] ? mid : right;
            }else {
                return left;
            }
        }else {
            if(array[right] > array[mid]) {
                return array[mid] > array[left] ? mid : left;
            }else {
                return right;
            }
        }
    }

    //小区间优化的直接插入排序代码
    public void insertSort(int[] array, int begin, int end) {
        for(int i = begin + 1; i <= end; i++) {
            int tmp = array[i];
            int pos = i - 1;
            for(int j = i - 1; j >= begin; j--) {
                if(array[j] > tmp) {
                    array[j+1] = array[j];
                    pos--;
                }else {
                    break;
                }
            }
            array[pos+1] = tmp;
        }
    }

非递归实现

    public void quickSortNoR(int[] array) {
        
        Stack<Integer> stack = new Stack<>();
        stack.push(array.length - 1);
        stack.push(0);
        
        while(!stack.isEmpty()) {
            int begin = stack.pop();
            int end = stack.pop();
            int key = array[begin];
            int left = begin;
            int right = end;
            int pivot = begin;
            while(left < right) {
                while(left < right && array[right] >= key) {
                    right--;
                }
                array[pivot] = array[right];
                pivot = right;

                while(left < right && array[left] <= key) {
                    left++;
                }
                array[pivot] = array[left];
                pivot = left;
            }
            array[pivot] = key;
            if(end - pivot - 1 > 1) {
                stack.push(end);
                stack.push(pivot + 1);
            }
            if(pivot - 1 - begin > 1) {
                stack.push(pivot - 1);
                stack.push(begin);
            }
        }
    }

复杂度和稳定性

时间复杂度O(N*log2N)

尽管快速排序的最坏时间复杂度为:O(N^2),但快速排序的时间复杂度为O(N*log2N)是约定俗成的,我们可以通过例如三数取中来避免最坏情况的发生。

空间复杂度O(log2N)~O(N)

  • O(log2N)主要是递归调用栈所占据的空间。在平均情况下,递归深度接近O(log2N)
  • O(N):最坏空间复杂度,当数组已经接近有序或完全逆序时,递归深度达到n,因此递归调用栈占据的空间也达到n。

稳定性:不稳定


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

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

相关文章

【FICO】SAP财务模块中的统驭科目及特别总账详解

前言 统驭科目作为SAP FICO财务模块中专有的一个概念&#xff0c;很好地展示了SAP ERP系统在设计模式中的精妙性。在本文中&#xff0c;笔者将详细地介绍统驭科目的设计初衷&#xff0c;作用以及如何在系统中进行使用。 统驭科目的设计初衷 统驭科目是如何进行核算的&#xff…

【python】OpenCV—Age and Gender Classification

文章目录 1、任务描述2、网络结构2.1 人脸检测2.2 性别分类2.3 年龄分类 3、代码实现4、结果展示5、参考 1、任务描述 性别分类和年龄分类预测 2、网络结构 2.1 人脸检测 输出最高的 200 个 RoI&#xff0c;每个 RoI 7 个值&#xff0c;&#xff08;xx&#xff0c;xx&#x…

LeetCode - 17 电话号码的字母组合

题目来源 17. 电话号码的字母组合 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对…

共享单车轨迹数据分析:以厦门市共享单车数据为例(三)

本篇文章将视角聚焦于共享单车的出行距离和时间分布&#xff0c;为了更好地理解共享单车在特定时间段内的使用情况及用户行为特征&#xff0c;本文基于2020年12月21日上午06:00至10:00期间收集的共享单车订单数据进行了详细的分析&#xff0c;旨在探索共享单车在该时间段内的出…

Centos7 Hadoop 单机版安装教程(图文)

本章教程,主要记录如何在Centos7中安装Hadoop单机版。 一、软件安装包和基础环境 CentOS7.x,jdk8,hadoop 通过网盘分享的文件:Hadoop 链接: https://pan.baidu.com/s/1_qGI9QeXMAJNb3TydHhQGA?pwd=xnz4 提取码: xnz4 当然你也可以自己去官网下载。 java8:https://www.ora…

【Python第三方库】OpenCV库实用指南

文章目录 前言安装OpenCV读取图像图像基本操作获取图像信息裁剪图像图像缩放图像转换为灰度图图像模糊处理边缘检测图像翻转图像保存 视频相关操作方法讲解读取视频从摄像头读取视频 前言 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;作为一个强大的计…

使用docker配置wordpress

docker的安装 配置docker yum源 sudo yum install -y yum-utils sudo yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo下载最新版本docker sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-…

基于spring拦截器实现博客项目的强制登录功能(四)

6. 强制登录 当⽤⼾访问 博客列表和博客详情⻚ 时, 如果⽤⼾当前尚未登陆, 就⾃动跳转到登陆⻚⾯. 我们可以采⽤拦截器来完成, token通常由前端放在header中, 我们从header中获取token, 并校验 token是否合法 6.1 添加拦截器 package com.example.spring_blog_24_9_8.config;…

k8s dashboard token 生成/获取

创建示例用户 在本指南中&#xff0c;我们将了解如何使用 Kubernetes 的服务帐户机制创建新用户、授予该用户管理员权限并使用与该用户绑定的承载令牌登录仪表板。 对于以下每个和的代码片段ServiceAccount&#xff0c;ClusterRoleBinding您都应该将它们复制到新的清单文件(如)…

Blazor开发框架Known-V2.0.10

Known今天迎来了2.0的第11个版本&#xff0c;同时网站网址和板块也进行了一次升级改造&#xff0c;虽不完美&#xff0c;但一直在努力改变&#xff0c;之前一直在完善框架功能&#xff0c;忽略了文档的重要性&#xff0c;所以这次更新了文档和API。交流互动板块也在进行当中&am…

PPT幻灯片的添加与编辑:全面技术指南

目录 一、PPT幻灯片的添加 1.1 启动PowerPoint与新建演示文稿 1.2 选择模板 1.3 添加新幻灯片 1.3.1 使用“开始”选项卡 1.3.2 使用快捷键 1.3.3 复制现有幻灯片 1.4 调整幻灯片顺序 二、PPT幻灯片的编辑 2.1 输入与编辑文本 2.1.1 使用文本框添加文本 2.1.2 使用占…

GitHub Star 数量前 13 的自托管项目清单

一个多月前&#xff0c;我们撰写并发布了这篇文章《终极自托管解决方案指南》。在那篇文章里我们深入探讨了云端服务与自托管方案的对比、自托管的潜在挑战、如何选择适合自托管解决方案&#xff0c;并深入介绍了五款涵盖不同场景的优秀自托管产品。 关于自托管的优势&#xf…

职业技能大赛背景下的移动互联网应用软件开发(Android)实训室建设方案

一、建设背景 随着科技的持续进步&#xff0c;移动设备已成为人们日常生活中不可或缺的一部分。据相关数据&#xff0c;移动互联网的使用率在近年来显著上升。在这样的背景下&#xff0c;移动互联技术不仅推动了科技的发展&#xff0c;也渗透到了智能家居、车联网、工业自动化…

大数据-129 - Flink CEP 详解 Complex Event Processing - 复杂事件处理

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

改进版field-sensitive指针分析算法

DEA 1.Introduction2.Approach2.1.Stride-based Field Representation2.1.1.示例12.1.2.示例2 2.2.完整算法 3.Evaluation3.1.Implementation3.2.结果 参考文献 1.Introduction 这篇paper是SVF团队对PKH field-sensitive指针分析算法 [ 2 ] ^{[2]} [2] 的优化&#xff0c;在使…

Pycharm中python文件导入torch模块时报错:No module named ‘torch‘

问题描述 导入torch时报错 上网查找后&#xff0c;发现原因可能是没有安装pytorch&#xff0c;但检查后发现自己已经安装了&#xff0c;遂考虑到可能是没有使用正确的环境 解决方法 因为是PyCharm 没有使用我所安装了 PyTorch 的 Conda 环境&#xff0c;所以报错了&#xf…

计算2的100次方

#include <stdio.h>int main() {int a[100] {0};a[0] 1;for(int i 0;i < 100;i)//乘100次2{for(int j 0; j < 100;j)//乘以每一位{a[j] * 2;//每一位都*2}for(int k 0;k < 99;k){if(a[k] > 10)//判断进位{a[k 1];a[k] - 10;}}}//找到第一个不为0的数&a…

vue part 9

动画与过渡 Test.vue <template><div><button click"isShow !isShow">显示/隐藏</button><transition name"hello" appear><h1 v-show"isShow">你好啊!</h1></transition><transition …

51单片机快速入门之点灯 STC 51单片机

第一步创建工程 第二步加载头文件 第三步编写代码 点灯完成 解释:主函数为main() 内部P1控制的是p1.0-p1.7 引脚 0为低电平

银河麒麟国产化系统(或者是Linux)一键安装docker和docker-compose

在国产化化机器上离线安装docker和docker-compose 第一步&#xff0c;查询国产化系统的cpu架构 使用如下命令都可以查询出来&#xff1a; # 查询全部 uname -a # 只查询部分 uname -p # 查了cpu 列表 lscpu 查询示例如下&#xff1a; 为麒麟桌面版 为麒麟服务版 第二步&a…