Java(三十) --- 基于比较的七大比较的排序算法(巨详细)

文章目录

  • 前言
  • 1. 排序的概念和引用
  • 2.直接插入排序
  • 3.希尔排序(缩小增量排序)
  • 4. 直接选择排序
  • 5. 堆排序
  • 6. 冒泡排序
  • 7.快速排序
    • 7.1.Hoare法
    • 7.2.挖坑法
    • 7.3.快速排序的优化
    • 7.4.非递归方法
  • 8.归并排序
    • 8.1.递归方法
    • 8.2.非递归方法
    • 8.3 海量数据的排序问题
  • 9. 七大比较排序的复杂度以及稳定性分析


前言

我们这个博客讲一下七大基于比较的排序
其中算法的动态演示网站:
https://www.cs.usfca.edu/~galles/visualization/Algorithms.html


1. 排序的概念和引用

排序: 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作

稳定性: 假设在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i] = r[j],且r[i] 在 r[j] 之前,而在排序后的序列中,r[i] 仍在 r[j] 之前,则称这种排序算法是稳定的;否则称为不稳定的。
在这里插入图片描述
**内部排序:**数据元素全部放在内存中的排序
**外部排序:**数据元素太多不能同时放在内存中,根据排序过程的要求不能内外存之间移动数据的排序
排序算法:

  • 基于比较的排序算法:
    • 插入排序
      • 直接排序
      • 希尔排序
    • 选择排序
      • 选择排序
      • 堆排序
    • 交换排序
      • 冒泡排序
      • 快速排序
    • 归并排序
  • 基于非比较的排序算法:
    • 计数排序
    • 基数排序
    • 统计数

2.直接插入排序

直接插入排序是一种简单的插入排序法,其基本思想:
把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的小有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。实际中我们玩扑克牌时,就用了插入排序的思想。

在这里插入图片描述

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

插入排序


为了统一:下面所有的数字都是 从小到大排序
思路:从数组下标为1开始(使用i变量),进行排序,因为第一个数字(下标为0)本来就是有序的, 然后 用 tmp 变量保存 arr[i] (tmp = arr[i]),此时使用变量 j 来遍历 i 之前的子数组,因为该子数组是有序的,判断 arr[j] 和 tmp的大小,如果 arr[j] > tmp,此时 arr[j+1] = arr[j],使得arr[j]往后移动,如果 arr[j] <= tmp,此时tmp找到了要填充的地方,arr[j+1] = tmp,然后break,因为已经可以确定 此时 子数组一定是有序的。如果都最后遍历完整个数组,都没有放好位置,那么说明 tmp 是最小的,此时 直接把 arr[j+1] = tmp,因为此时 j = -1

public static void insertSort(int[] array){
        for(int i = 1;i<array.length;i++){
            int tmp = array[i];
            int j = i-1;
            for (;j>=0;j--){
                if (array[j] > tmp){
                    array[j+1] = array[j];
                }else {
                    array[j+1] = tmp;
                    break;
                }
            }
            array[j+1] = tmp;
        }
    }

直接插入排序的特性总结:

  1. 元素集合越接近有序,直接插入排序算法的时间效率越高
  2. 时间复杂度:O(n^2)
  3. 空间复杂度:O(1)
  4. 稳定性:稳定

3.希尔排序(缩小增量排序)

希尔排序法又称为缩小增量法。希尔排序法的基本思路:先选定一个整数,把待排序文件汇中所有记录分成多个组,所有距离一样的记录分在同一组内,并对每一组内的记录进行排序,然后,重复上述的分组和排序的工作。当达到=1时,记录在统一组内排好序。

在这里插入图片描述

思路:希尔排序的基本思路跟直接插入排序一样,主要就是牵扯到分组,下面我们来写一下带代码

希尔排序

public static void shellSort(int[] array){
        int gap = array.length;
        while (gap > 1){ 
            // gap 不能大于等于 1,因为如果 gap = 1,此时进入循序,
            // gap = 0,那么下面的shell 进入到死循环
            gap /= 2;
            shell(array,gap);
        }
    }

    private static void shell(int[] array, int gap) {
        for(int i = 0;i<array.length;i+=gap){
            int tmp = array[i];
            int j = i - gap;
            for (;j>=0;j-=gap){
                if (array[j] > tmp){
                    array[j+gap] = array[j];
                }else{
                    array[j+gap] = tmp;
                    break;
                }
            }
            array[j+gap] = tmp;
        }
    }

希尔排序的特性总结:

  1. 希尔排序是对直接排序的优化
  2. 当 gap > 1 时都是预排序,目的是让数组更接近于有序。当 gap == 1时,数组已经接近有序,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的优化。
  3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些书中给出的希尔排序的时间复杂度都不固定
    在这里插入图片描述
  4. 稳定性:不稳定

4. 直接选择排序

基本思路:
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
还是以 从小到大进行排序
先从array[i] ~ array[n-1]中选择最小的数据元素
如果不是第一个元素(array[0])的话,就跟第一个元素进行交换,然后在剩余的数组中,重复上述操作,直到集合剩余一个元素

直接选择排序

在这里插入图片描述

  public static void selectSort2(int[] array){
        int n = array.length;
        for(int i = 0;i<n;i++){
            int minIndex = i;
            for(int j = i+1;j < n;j++){
                if (array[minIndex] > array[j]){
                    minIndex = j;
                }
            }
            swap(array,minIndex,i);
        }
    }
    private static void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

上面这个代码是只找最小下标的值,下面是对上面的代码进行一次优化,从两边一起找。
在这里插入图片描述
下来我们编写代码:

	public static void selectSort(int[] array){
        int left = 0,right = array.length - 1;
        while (left <= right){
            int maxIndex = left,minIndex = left;
            for (int i = left+1; i <= right; i++) {
                if (array[i] > array[maxIndex]){
                    maxIndex = i;
                }
                if (array[i] < array[minIndex]){
                    minIndex = i ;
                }
            }
            swap(array,minIndex,left);
            if (maxIndex == left){
                maxIndex = minIndex;
            }
            swap(array,maxIndex,right);
            left++;
            right--;
        }
    }
	private static void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

直接选择排序的特性总结:

  1. 直接选择排序思考非常好理解,但是效率不是很少,实际中很少使用
  2. 时间复杂度:O(n^2)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定

5. 堆排序

堆排序(HeapSort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,他是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆
这个堆排序在咱们的Java(二十六)—优先级队列(堆)中提及到了,载着我们再讲一遍,并且从小到大进行排列

堆排序


在这里插入图片描述

下来我们来编写代码:

 public static void heapSort(int[]array){
        createHeap(array);
        int end = array.length-1;
        while (end > 0){
            swap(array,0,end);
            shitDown(array,0,end);
            end--;
        }
    }

    private static void shitDown(int[] array, int parent, int length) {
        int child = 2 * parent + 1;
        while (child < length){
        	// 用来判断 child + 1 这个是否合法,并且判断 child 和 child + 1 谁大谁小
                if (child + 1 < length && array[child] < array[child + 1]){
                child++;
            }
            if (array[child] > array[parent]){
                swap(array,child,parent);
                parent = child;
                child = 2 * parent + 1;
            }else {
                break;
            }
        }
    }

    private static void createHeap(int[] array) {
        for(int parent = (array.length - 1 - 1)/2;parent >= 0;parent--){
            shitDown(array,parent, array.length);
        }
    }
    private static void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

堆排序的特性总结

  1. 堆排序使用堆来选数,效率就高了很多
  2. 时间复杂度:O(n*logn)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定

6. 冒泡排序

冒泡排序

在这里插入图片描述
上面就是冒泡排序的流程图
其中定义一个变量 i ,用于记录排序的趟数,j用于交换两个数,下面我们编写一下代码

	public static void bubbleSort(int[] array){
        for (int i = 0;i<array.length-1;i++){
            for (int j = 0;j<array.length-i-1;j++){
                if (array[j] > array[j+1]){
                    swap(array,j,j+1);
                }
            }
        }
    }
    private static void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

其中我们还可以进行优化
我们添加一个变量 flg,用于记录这一趟是否进行了交换元素的操作,如果这一趟没有交换元素,那么说明后面的元素都是有序的,因此这一趟提前就结束,直接break

	public static void bubbleSort(int[] array){
        for (int i = 0;i<array.length-1;i++){
            boolean flg = false;
            for (int j = 0;j<array.length-i-1;j++){
                if (array[j] > array[j+1]){
                    swap(array,j,j+1);
                    flg = true;
                }
            }
            if (!flg){
                break;
            }
        }
    }
    private static void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

冒泡排序的特性总结:

  1. 冒泡排序是一种非常容易理解的排序
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)
  4. 稳定性:稳定

7.快速排序

快速排序是 Hoare 于1962年提出的一种二叉树交换排序的方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两个字序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后左右子序列重复该过程,直到所有元素都排列在相应位置上为止

快速排序

在这里插入图片描述
这个便是大致的流程.

	public static void quickSort(int[] array){
        quick(array,0,array.length-1);
    }

    private static void quick(int[] array, int start, int end) {
        if (start >= end){
            return;
        }
        int pivot = partition(array,start,);
        quick(array,start,pivot-1);
        quick(array,pivot+1,end);
    }

上述为快速排序递归实现的主框架,发现与二叉树前序遍历规则非常像,同学们在写递归框架时可想想二叉树前序
遍历规则即可快速写出来,后序只需分析如何按照基准值来对区间中数据进行划分的方式即可。
将区间按照基准值划分为左右两半部分的常见方式有:

7.1.Hoare法

在这里插入图片描述

private static int partition(int[] array, int left, int right) {
        int tmpleft = left;
        int pivot = array[left];
        while (left < right){
            while (left < right && array[right] >= pivot){
                right--;
            }
            while (left < right && array[left] <= pivot){
                left++;
            }
            swap(array,left,right);
        }
        swap(array,tmpleft,left);
        return left;
    }

其中有两个小细节问题,给大家说一下:

  1. 为什么要先从后往前找下一个right,而不是先从前往后中找下一个left
    我们就动态演示一下呗。
    在这里插入图片描述
    此时我们发现,9这个数字竟然在 6 的左边,显然不符合我们的预期,因此不能这样写
  2. 为什么是array[right] >= pivot,而不是array[right] > pivot
    需要考虑循环问题
    在这里插入图片描述

7.2.挖坑法

在这里插入图片描述

下面我们根据上面的图,来编写一下代码

/*
    挖坑法
     */
    private static int partition(int[] array, int left, int right) {
        int tmp = array[left];
        while (left < right){
            while (left < right && array[right] >= tmp ){
                right--;
            }
            array[left] = array[right];
            while (left < right && array[left] <= tmp){
                left++;
            }
            array[right] = array[left];
        }
        array[left] = tmp;
        return left;
    }

7.3.快速排序的优化

  1. 三数取中法选 key
    顾名思义,就是从left ,right,以及这两个元素的一半数,查找中间的数,让他成为一个基准值,这样就可以快速提高效率
public static void quickSort(int[] array){
        quick(array,0,array.length-1);
    }

    private static void quick(int[] array, int start, int end) {
        if (start >= end){
            return;
        }
        int midIndex = getMiddle(array,start,end);
        swap(array,midIndex,start);
        int pivot = partition(array,start,end);
        quick(array,start,pivot-1);
        quick(array,pivot+1,end);
    }
    private static int getMiddle(int[]array,int left,int right) {
        int mid = (left + right)/2;
        if (array[left] < array[right]){
            if (array[mid] < array[left]){
                return left;
            } else if (array[right] < array[mid] ) {
                return right;
            }else {
                return mid;
            }
        }else {
            if (array[right] < array[mid]){
                return right;
            }else if (array[mid] > array[left]){
                return left;
            }else {
                return mid;
            }
        }
    }
    /*
    挖坑法
     */
    private static int partition(int[] array, int left, int right) {
        int tmp = array[left];
        while (left < right){
            while (left < right && array[right] >= tmp ){
                right--;
            }
            array[left] = array[right];
            while (left < right && array[left] <= tmp){
                left++;
            }
            array[right] = array[left];
        }
        array[left] = tmp;
        return left;
    }
    private static void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
  1. 递归到小的子区间中,可以考虑使用插入排序
    我们知道,直接插入排序,数组越有序,排序的速度越快,例如,当子数组的长度只剩下5个之后,选择插入排序,下面我们写一下代码
public static void quickSort(int[] array){
        quick(array,0,array.length-1);
    }

    private static void quick(int[] array, int start, int end) {
        if (start >= end){
            return;
        }
        if (end - start + 1 <= 5){
            insertSortRange(array,start,end);
            return;
        }
        int midIndex = getMiddle(array,start,end);
        swap(array,midIndex,start);
        int pivot = partition(array,start,end);
        quick(array,start,pivot-1);
        quick(array,pivot+1,end);
    }

    private static void insertSortRange(int[] array, int start, int end) {
        for(int i = start + 1;i <= end;i++){
            int tmp = array[i];
            int j = i - 1;
            for (;j >= start; j--){
                if (array[j] > tmp){
                    array[j+1] = array[j];
                }else {
                    array[j+1] = tmp;
                    break;
                }
            }
            array[j+1] = tmp;
        }
    }

7.4.非递归方法

在这里插入图片描述

public static void quickSort(int[] array){
     quickNor(array,0,array.length-1);
    }
    public static void quickNor(int[] array,int start,int end) {
        Stack<Integer> stack = new Stack<>();
        int pivot = partition(array,start,end);
        if (pivot > start + 1){
            stack.push(start);
            stack.push(pivot-1);
        }
        if (pivot < end - 1){
            stack.push(pivot+1);
            stack.push(end);
        }
        while (!stack.isEmpty()){
            end = stack.pop();
            start = stack.pop();
            pivot = partition(array,start,end);
            if (pivot > start + 1){
                stack.push(start);
                stack.push(pivot-1);
            }
            if (pivot < end - 1){
                stack.push(pivot+1);
                stack.push(end);
            }
        }
    }

快速排序总结:

  1. 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫做 快速 排序
  2. 时间复杂度:O(n*logn)
  3. 空间复杂度:O(logn)
  4. 稳定性:不稳定

8.归并排序

归并排序(merge-sort)是建立在归并排序操作上的一种有效的排序算法,算法采用分治法(Divide and Conquer)

归并排序

在这里插入图片描述

8.1.递归方法

前面的分解操作,属于递归操作,跟上面的快速排序一样,在这就不做讨论
下面的是合并:这个操作也比较简单,大家看一下下面的代码,自行领悟一下

public static void mergeSort(int[]array){
        mergeSortTmp(array,0,array.length-1);
    }

    private static void mergeSortTmp(int[] array, int left, int right) {
        if (left > right) {
            return;
        }
        int mid = (left + right)/2;
        // 分解操作:递归
        mergeSortTmp(array,left,mid);
        mergeSortTmp(array,mid+1,right);
        // 合并:合并两个有序数组
        merge(array,left,mid,right);

    }

    private static void merge(int[] array, int left, int mid, int right) {
        int[] tmp = new int[right - left + 1];
        int k = 0;
        int s1 = left,e1 = mid,s2 = mid+1,e2 = right;
        while (s1 <= mid && s2 <= right){
            if (array[s1] <= array[s2]){
                tmp[k++] = array[s1++];
            }else {
                tmp[k++] = array[s2++];
            }
        }
        while (s1 <= mid){
            tmp[k++] = array[s1++];
        }
        while (s2 <= right){
            tmp[k++] = array[s2++];
        }
        for (int i = 0; i < k;i++){
            array[i+left] = tmp[k];
        }
    }

8.2.非递归方法

上面递归的逻辑,主要是找到 left right mid的位置,只要找到 这三个位置,就可以调用 merge 方法
使用 gap 来表示 每个分组的数组内元素个数,left = i,mid = left + gap -1,right = mid + gap
然后 把这三个参数放到 merge 方法中
在这里插入图片描述

public static void mergeSort(int[]array){
        //mergeSortTmp(array,0,array.length-1);
        mergeSortNor(array);
    }

    private static void mergeSortNor(int[] array) {
        int gap = 1;
        while (gap < array.length){
            for (int i = 0;i<array.length;i = i + gap * 2){
                int left = i;
                int mid = left + gap - 1;
                if (mid > array.length){
                    mid = array.length - 1;
                }
                int right = mid + left;
                if (right > array.length){
                    right = array.length - 1;
                }
                merge(array,left,mid,right);
            }
            gap *= 2;
        }
    }
    private static void merge(int[] array, int left, int mid, int right) {
        int[] tmp = new int[right - left + 1];
        int k = 0;
        int s1 = left,e1 = mid,s2 = mid+1,e2 = right;
        while (s1 <= mid && s2 <= right){
            if (array[s1] <= array[s2]){
                tmp[k++] = array[s1++];
            }else {
                tmp[k++] = array[s2++];
            }
        }
        while (s1 <= mid){
            tmp[k++] = array[s1++];
        }
        while (s2 <= right){
            tmp[k++] = array[s2++];
        }
        for (int i = 0; i < k;i++){
            array[i+left] = tmp[k];
        }
    }

归并排序总结

  1. 归并排序的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。
  2. 时间复杂度:O(N*logN)
  3. 空间复杂度:O(N)
  4. 稳定性:稳定

8.3 海量数据的排序问题

外部排序:排序过程需要在磁盘等外部存储进行的排序
前提:内存只有 1G,需要排序的数据有 100G
因为内存中无法把所有数据全部放下,所以需要外部排序,而归并排序是最常用的外部排序

  1. 先把文件切分成 200 份,每个 512M
  2. 分别对 512M M排序。
  3. 进行二路归并,同时对2000份有序文件做归并过程,最终结果就有序了

9. 七大比较排序的复杂度以及稳定性分析

在这里插入图片描述

排序方法最好平均最坏空间复杂度稳定性
冒泡排序O(n)O(n^2)O(n^2)O(1)稳定
插入排序O(n)O(n^2)O(n^2)O(1)稳定
选择排序O(n^2)O(n^2)O(n^2)O(1)不稳定
希尔排序O(n)O(n^1.3)O(n^2)O(1)不稳定
堆排序O(n*logn)O(n*logn)o(n*logn)O(1)不稳定
快速排序O(n*logn)O(n*logn)O(n^2)O(logn) - O(n)不稳定
归并排序O(n*logn)O(n*logn)O(n*logn)O(n)稳定

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

构建安全基石:网络安全等级保护定级指南

在数字化时代&#xff0c;网络安全已成为企业与个人不可忽视的重要课题。网络安全等级保护定级指南&#xff0c;作为国家指导网络安全保护的重要文件&#xff0c;为各类机构提供了精准的安全防护蓝图。本文旨在深度解析网络安全等级保护定级指南的精髓&#xff0c;助力建构全面…

Docker-在Centos中部署Shell脚本获取镜像并构建容器

环境准备 1.Centos 7系统 参考&#xff1a;Centos安装 2.demo镜像推送到阿里云 参考demo镜像推送到阿里云 Centos操作 1.修改demo中相关配置springboot-docker-demo\bin\docker-deploy.sh ## 仓库地址 REGISTRY_SERVER公有网络域名 ## 用户名 USERNAME阿里云账号 ## 密码 P…

背包问题全解

文章目录 01背包一、01背包模板二、采药三、装箱问题四、宠物小精灵之收服五、数字组合 完全背包六、完全背包模板七、买书八、货币系统&#xff08;简单版&#xff09;九、货币系统&#xff08;进阶版&#xff09; 01背包 一、01背包模板 还有个疑惑&#xff0c;为什么最大价…

【高阶数据结构】红黑树的插入(超多精美图解+完整代码)

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《高阶数据结构》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多《高阶数据结构》点击专栏链接查看&a…

51单片机应用开发(进阶)---外部中断(按键+数码管显示0-F)

实现目标 1、巩固数码管、外部中断知识 2、具体实现&#xff1a;按键K4&#xff08;INT1&#xff09;每按一次&#xff0c;数码管从0依次递增显示至F&#xff0c;再按则循环显示。 一、共阳数码管 1.1 共阳数码管结构 1.2 共阳数码管码表 共阳不带小数点0-F段码为&#xff…

MacOS上Homebrew 安装、配置、更改国内镜像源及使用教程

Homebrew笔记 1. 介绍 官网&#xff1a;https://brew.sh/ 对于习惯了使用命令来完成一切的程序员来说&#xff0c;安装软件这种小事&#xff0c;自然是能够用命令解决&#xff0c;就不用图形界面选择。但是在 Linux 中&#xff0c;我们有 yum、apt、dnf、pkg等命令来完成软件的…

LeetCode 热题 100之链表1

1.相交链表 思路分析&#xff08;直接上双指针&#xff09;&#xff1a; 初始化两个指针&#xff0c;分别指向两个链表的头节点 headA 和 headB遍历两个链表&#xff0c;当指针到达链表的末尾时&#xff0c;将指针移动到另一个链表的头部 如果链表相交&#xff0c;两个指针会在…

【含开题报告+文档+PPT+源码】基于SSM的旅游与自然保护平台开发与实现

开题报告 围场县拥有丰富的自然景观和野生动植物资源&#xff0c;同时面临着旅游业发展和自然保护之间的平衡问题&#xff0c;通过强调自然保护&#xff0c;这个平台可以教育游客如何尊重和保护当地的生态环境。同时&#xff0c;平台还可以提供关于生态保护的信息&#xff0c;…

立仪光谱共焦在玻璃上奥秘与应用

在现代工业和科学研究中&#xff0c;玻璃因其透明、坚硬和易加工的特性被广泛应用于各个领域。然而&#xff0c;玻璃的厚度测量一直是困扰业界的一大难题。传统的千分尺或电容式传感器虽然在一定程度上能满足生产需求&#xff0c;但在精度、效率以及适用范围上存在明显的局限。…

中航资本:市盈率静和动分别是什么意思?市盈率静和动看哪个准?

市盈率静和动别离是什么意思&#xff1f; 市盈率静就是指静态市盈率&#xff0c;是以最新一期的年报为核算根据&#xff0c;其数据核算公式为&#xff1a;总市值最新一期的年报的净利润&#xff0c;年报的净利润可所以作用快报或作用预告发布的数据。 市盈率动就是动态市盈率…

动态规划 - 背包问题 - 完全背包

完全背包物品数量无限制&#xff0c;可以使用多次的实现方式&#xff1a;背包正序遍历 0-1背包&#xff1a;先物品后背包&#xff0c;物品正序、背包倒序&#xff08;保证每个物品只用一次&#xff09; 完全背包&#xff1a;先后顺序都可以&#xff0c;物品正序、背包正序 如果…

基于卷积神经网络的苹果病害识别与防治系统,resnet50,mobilenet模型【pytorch框架+python源码】

更多目标检测和图像分类识别项目可看我主页其他文章 功能演示&#xff1a; 苹果病害识别与防治系统&#xff0c;卷积神经网络&#xff0c;resnet50&#xff0c;mobilenet【pytorch框架&#xff0c;python源码】_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于卷积…

appium+mumu模拟器 嚼碎菜鸟教程

1、android sdk 下载安装 下载地址&#xff1a;https://www.androiddevtools.cn/index.html# 选择版本&#xff1a;android sdk【sdk tools:installer_r24.4.1-windows.exe】 参考步骤&#xff1a;https://blog.csdn.net/2401_83004375/article/details/139300339 2、jdk 安装…

day11:磁盘管理

一&#xff0c;磁盘概述 磁盘概述 磁盘是一种持久性存储设备&#xff0c;用于存储操作系统、应用程序和数据。磁盘通常分为**机械硬盘&#xff08;HDD&#xff09;和固态硬盘&#xff08;SSD&#xff09;**两种&#xff0c;HDD 基于旋转的磁性盘片&#xff0c;而 SSD 基于闪存…

【WRF数据处理】基于GIS4WRF插件将geotiff数据转为tiff(geogrid,WPS所需数据)

【WRF数据处理】基于GIS4WRF插件将geotiff数据转为tiff&#xff08;geogrid&#xff0c;WPS所需数据&#xff09; 数据准备&#xff1a;以叶面积指数LAI为例QGis实操&#xff1a;基于GIS4WRF插件将geotiff数据转为tiff警告&#xff1a;GIS4WRF: Input layer had an unexpected …

ES8JC-ASEMI超快恢复二极管ES8JC

编辑&#xff1a;ll ES8JC-ASEMI超快恢复二极管ES8JC 型号&#xff1a;ES8JC 品牌&#xff1a;ASEMI 封装&#xff1a;SMC 安装方式&#xff1a;贴片 批号&#xff1a;最新 恢复时间&#xff1a;35ns 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;8A 最大循…

ECCV 2024论文分享┆Agent Attention: Softmax注意力和线性注意力的高效融合

简介 本推文主要介绍了由清华大学黄高老师团队发表在ECCV 2024上的一篇论文《Agent Attention: On the Integration of Softmax and Linear Attention》&#xff0c;文中提出了一种新型的代理注意力&#xff08;Agent Attention&#xff09;。近年来&#xff0c;Transformer在…

Github 2024-10-29Python开源项目日报 Top10

根据Github Trendings的统计,今日(2024-10-29统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10TypeScript项目1gpt4free存储库:强大语言模型的集合 创建周期:300 天开发语言:Python协议类型:GNU General Public License v3…

【Java】逻辑控制 —— 三大结构 和 猜数字游戏

目录 1. 顺序结构 2. 分支结构【与C略有不同】 2.1 if语句 2.2 switch语句 注意事项【与C不同】 3. 循环结构【与C略有不同】 3.1 while循环 * break和continue 3.2 for循环 3.3 do while循环 * 输入的判断&#xff08;hasNext&#xff09; 4. 猜数字游戏 1. 顺序结…

大文件秒传,分片上传,断点续传

大文件分片上传 一 功能描述 1.文件通过web端分片多线程上传到服务端&#xff0c;然后web端发起分片合并&#xff0c;完成大文件分片上传功能 2.上传过的大文件&#xff0c;实现秒传 3.上传过程中&#xff0c;服务异常退出&#xff0c;实现断点续传 二 流程图 三 代码运行…