Java十大经典排序算法

news2024/11/19 5:31:06

目录

    • 1. 插入类排序
      • 1.1 直接插入排序
      • 1.2 希尔排序
    • 2. 选择类排序
      • 2.1 直接选择排序
      • 2.2 堆排序
    • 3. 交换类排序
      • 3.1 冒泡排序
      • 3.2 快速排序(递归)
        • 3.2.1 快排的优化
      • 3.3 快速排序(非递归——栈)
    • 4. 归并类排序
      • 4.1 二路归并排序(递归)
    • 5. 基于比较的排序总结
    • 6. 非比较类排序
      • 6.1 计数排序
      • 6.2 基数排序
      • 6.3 桶排序

1. 插入类排序

1.1 直接插入排序

  1. 思想:
    可以理解为打扑克牌的时候,给扑克牌会进行插入排序。
    ①一开始抓到一张“3”,默认是有序的;
    ②第二次抓到“5”,与3比较,比3大,应该插入在3的后面;
    ③第三次抓到“4”,与5比较,比5小,则把5后移一个位置,继续与3比较,比3大,因此插入到“3”和“5”之间。
    注意:需要一开始就用tmp记录待插入的值,不然会导致最后值被覆盖。

即,把n个元素分为有序列和无序列,刚开始时,有序列默认是1个元素,无序列时剩余的n-1个元素,每次从无序列种取出1个元素与有序列进行排序,最终得到一个排序好的有序列。

  1. 实现:
 public static void insertSort(int[] nums) {
        for (int i = 1; i < nums.length; i++) {
            int tmp = nums[i];
            int j = i-1;
            for (; j >= 0; j--) {
                if (tmp < nums[j]) {
                    nums[j+1] = nums[j];
                }else {
                    break;
                }
            }
            nums[j+1] = tmp;
            System.out.println("第"+ i + "次排序后结果为:" +Arrays.toString(nums));
        }
    }
  1. 分析:
    稳定性:稳定
    时间复杂度:O(n的平方)【最坏】,O(n)【最好】,O(n的平方)【平均】
    空间复杂度:O(1)
    元素越有序,直接插入排序速度越快【对数据敏感
    运行结果:
    在这里插入图片描述
    序列为int[] nums = {9,1,3,2,4,8,5};
    默认有序列{9},无序列{1,3,2,4,8,5}
    ①待排序{1}排序后,有序列{1,9},无序列{3,2,4,8,5}
    记录1(防后移被覆盖),1比9小,所以需要将9后移,最后将1放在空位(9原本的位置)
    ②待排序{3},排序后,有序列{1,3,9},无序列{2,4,8,5}
    记录3(防后移被覆盖),3比9小,所以需要将9后移,3比1大,所以将3放在1和9之间(9原本的位置)
    ③待排序{2},排序后,有序列{1,2,3,9},无序列{4,8,5}
    记录2(防后移被覆盖),2比9小,所以需要将9后移,2比3小,所以需要将3后移,2比1大,所以将2放在1和3之间(3原本的位置)
    ④待排序{4},排序后,有序列{1,2,3,4,9},无序列{8,5}
    记录4(防后移被覆盖),4比9小,所以需要将9后移,4比3大,所以将4放在3和9之间(9原本的位置)
    ⑤待排序{8},排序后,有序列{1,2,3,4,8,9},无序列{5}
    记录8(防后移被覆盖),9比9小,所以需要将9后移,8比4大,所以将8放在4和9之间(9原本的位置)
    ⑥待排序{5},排序后,有序列{1, 2, 3, 4, 5, 8, 9},无序列{}
    记录5(防后移被覆盖),5比9小,所以需要将9后移,5比8小,所以需要将8后移,5比4大,所以将5放在4和8之间(8原本的位置)

1.2 希尔排序

  1. 思想:
    希尔排序是直接插入排序的优化,又叫缩小增量排序。

把整体元素以gap为间距进行分组,每组之间进行直接插入排序,排序完之后再以gap/2继续排序,直至gap为1为止。
本质是插入排序,只不过这个插入排序和gap有关系。

跳跃式的分组排序,可以尽量把小的数据快速往前移,把大的数据快速往后移(相对于相邻分组的好处)。

  1. 实现:
//控制增量gap的方法
public static void shellSort(int[] nums) {
        int gap = 5;
        while (gap >= 1) {
            shell(nums,gap);
            gap = gap / 2;
        }
    }
//真正排序的方法
public static void shell(int[] nums, int gap) {
        //直接插入排序+希尔
        for (int i = gap; i < nums.length; i += gap) {
            int tmp = nums[i];
            int j = i - gap;
            for (; j >= 0; j -= gap) {
                if (nums[j] > tmp) {
                    nums[j+gap] = nums[j];
                }else {
                    break;
                }
            }
            nums[j + gap] = tmp;
        }
    }
  1. 分析:
    稳定性:不稳定
    时间复杂度:O(n的1.3平方)【估计】,与gap增量有关
    空间复杂度:O(1)
    元素越有序,直接插入排序速度越快(理解成插入排序的优化)【对数据敏感
    序列为:{9,1,3,2,4,8,5,9,2,5,6,10}
    ①gap = 5;排序后为{6, 1, 3, 2, 4, 8, 5, 9, 2, 5, 9, 10}
    ②gap = 2;排序后为{2, 1, 3, 2, 4, 5, 5, 8, 6, 9, 9, 10}
    ③gap = 1;排序后为{1, 2, 2, 3, 4, 5, 5, 6, 8, 9, 9, 10}
    在这里插入图片描述
    每组的排序都是直接插入排序,数据在慢慢的变有序,插入排序的优点是越有序越快,所以不用担心每组的数据在在慢慢变多。

2. 选择类排序

2.1 直接选择排序

  1. 思想:

从待排序的元素中,每次直接选择出最小的元素放入已经排好序的序列中,以此类推。

每次默认待排序的元素是最小的,与其后面的无序的序列进行比较,如果有比它小的,则进行交换,以此类推,当无序序列走完的时候,可以选出最小的放入到排序好的序列后面。

  1. 实现:
    public static void select(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] > nums[j]) {
                    int tmp = nums[i];
                    nums[i] = nums[j];
                    nums[j] = tmp;
                }
            }
        }
    }

//或者把交换封装成方法
    public static void select(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            int min = i;
            int j = i + 1;
            for (; j < nums.length; j++) {
                if (nums[min] > nums[j]) {
                    min = j;
                }
            }
            if (min != i) {
                swap(nums,min,i);
            }
        }
    }
    private static void swap(int[] nums, int min, int i) {
        int tmp = nums[min];
        nums[min] = nums[i];
        nums[i] = tmp;
    }

  1. 分析:
    稳定性:不稳定【2 3 2 1 ,这样第一次会变成 1 3 2 2,2的相对位置发生了改变,所以是不稳定的】
    时间复杂度:O(n的平方)【没有好坏之分】
    空间复杂度:O(1)
    对数据不敏感,不管怎么样,都得把后面的比较完【不太适用】
    待排序序列为:9,1,3,8,11,6,10
    ①默认记录9为最小元素,1比9小,1和9交换位置(或者记录1为最小元素),后面的元素都没有比1小,故排序后结果为:[1, 9, 3, 8, 11, 6, 10]
    ②默认记录9为最小元素,3比9小,3和9交换位置,后面的元素都没有比3小,故排序后结果为:[1, 3, 9, 8, 11, 6, 10]
    ③默认记录9为最小元素,8比9小,8和9交换位置,6比8小,6和8交换位置,故排序后蝶国为:[1, 3, 6, 9, 11, 8, 10]
    ④默认记录9为最小元素,8比9小,8和9交换位置,[1, 3, 6, 8, 11, 9, 10]
    ⑤默认记录11为最小元素,9比11小,9和11交换位置,故排序后的结果为:[1, 3, 6, 8, 9, 11, 10]
    ⑥默认记录11为最小元素,10比11小,10和11交换位置,故排序后的结果为:[1, 3, 6, 8, 9, 10, 11]
    ⑦默认记录11为最小元素,11之后没有待排序的元素序列,故最终排序结果为:[1, 3, 6, 8, 9, 10, 11]
    在这里插入图片描述

2.2 堆排序

  1. 思想:

从小到大排序:建大根堆(堆顶元素是最大的,每次把堆顶元素与堆的最后一个元素进行交换,再重新调整堆,从而得到从小到大的序列)
从大到小排序:建小根堆(堆顶元素是最小的,每次把堆顶元素与堆的最后一个元素进行交换,再重新调整堆,从而得到从大到小的序列)
整体分2步:建堆+堆删除(都是向下调整算法)

  1. 实现:
class Solution {
    public int[] sortArray(int[] nums) {
        for (int i = (nums.length - 1 - 1) / 2; i >= 0; i--) {
            shiftDown(i,nums.length,nums);
        }
        int end = nums.length - 1;
        while (end > 0) {
            swap(nums,0,end);
            shiftDown(0,end,nums);
            end--;
        }
        return nums;
    }
    private void swap(int[] nums, int min, int i) {
        int tmp = nums[min];
        nums[min] = nums[i];
        nums[i] = tmp;
    }
    public void shiftDown(int parent, int len, int[] nums) {
        int child = parent * 2 + 1;
        while (child < len) {
            if (child + 1 < len && nums[child] < nums[child+1]) {
                child = child +1;
            }
            if (nums[child] < nums[parent]) {
                break;
            }else {
                swap(nums,child,parent);
                parent = child;
                child = parent * 2 + 1;
            }
        }
    }
}
  1. 分析:
    稳定性:不稳定
    时间复杂度:O(nlogn)
    空间复杂度:O(1)
    对数据不敏感,堆排序的前提是要建立一个大根堆/小根堆
    ①建立大根堆(向下调整)
    ②每次堆顶元素和堆尾元素交换,除去交换后的堆尾元素重新调整成堆,用end记录堆尾元素的位置,注意end是一直在变的。【换完了,就调整】

3. 交换类排序

3.1 冒泡排序

  1. 思路:

冒泡排序,前后两个元素两两比较,不满足排序情况则进行交换,就像冒泡一样,最后最大的元素像泡泡一样到了序列的最后面。

  1. 实现:
    ①基础优化版
 //冒泡排序
    public static void bubbleSort(int[] nums) {
        for (int i = 0; i < nums.length - 1; i++) {
            for (int j = 0; j < nums.length - 1 - i; j++) {
                if (nums[j] > nums[j+1]) {
                    swap(nums,j,j+1);
                }
            }

        }
    }
    private static void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }

②进阶优化版
我们发现如果某一趟没有发生元素交换则说明该序列已经有序了,因此可以设置标志位判断在一趟这元素有没有发生交换

    public static void bubbleSort(int[] nums) {
        for (int i = 0; i < nums.length - 1; i++) {
            boolean flag = false;
            for (int j = 0; j < nums.length - 1 - i; j++) {
                if (nums[j] > nums[j+1]) {
                    flag = true;
                    swap(nums,j,j+1);
                }
            }
            if (flag == false) {
                break;
            }
        }
    }
    private static void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
  1. 分析:
    稳定性:稳定
    时间复杂度:O(n的平方)
    空间复杂度:O(1)
    对数据敏感,如果一趟没有发生数据交换,则说明元素已经有序
    在这里插入图片描述
    外层循环表示需要冒泡排序的趟数
    内层循环表示需要比较的元素个数

3.2 快速排序(递归)

  1. 思路:

选定一个数为基准,比基准小的元素全放在基准左边,比基准大的元素全放在基准右边,左边和右边又递归重复上述过程,直到所有元素都排列在相应位置上。
是一种基于二叉树结构的交换排序

  1. 实现:
    //快速排序
    public static void quickSort(int[] nums) {
        quick(nums,0,nums.length-1);
    }
    //完成递归操作
    public static void quick(int[] nums, int left, int right) {
        if (left >= right) {
            return;
        }
        int div = partition(nums,left,right);
        quick(nums,left,div-1);
        quick(nums,div+1,right);
    }
    //基准划分操作
    public static int partition(int[] nums, int left, int right) {
        int pivot = nums[left];
        while (left < right) {
            while (left < right && nums[right] >= pivot) {
                right--;
            }
            nums[left] = nums[right];
            while (left < right && nums[left] <= pivot) {
                left++;
            }
            nums[right] = nums[left];
        }
        nums[left] = pivot;
        return left;
    }
  1. 分析:
    稳定性:不稳定(前后交换)
    时间复杂度:O(nlogn)【最好,满二叉树,完全二叉树,每次都能均匀分割待排序序列】,O(n平方)【最坏,有序/逆序,相当于只有左树/右树】
    空间复杂度:O(logn)【左树/右树高顿】,最坏为O(n)
    对数据敏感,元素越有序,快排越低效
    ①递归的出口为什么要取大于号?
    在这里插入图片描述
    假设待排序序列为 1 2 3 4
    那么基准为1,left为0,right为3
    right开始往前走,走到0位置和left相遇,方法结束
    下一次,left为0,right为-1,因此也不可以进行递归,而需直接返回,所以要取大于等于号。
    在这里插入图片描述

    ②循环的条件为什么要取等号?
    在这里插入图片描述
    假设不取等号,前后2个元素相等的情况下,会陷入死循环。
    例如,待排序序列为6 3 4 5 7 6,则会在第一个元素和最后一个元素之间反复横跳。
    在这里插入图片描述

    ③左边作为基准,为什么要先从右边开始走,而不先从左边走?
    在这里插入图片描述
    用Hoare法比挖坑法好解释。
    最终会造成把比基准大的数换到前面去。
    在这里插入图片描述
    快排有3种方法(是一个递归过程)
    ①Hoare版:left去找比基准小的,right去找比基准大的,找到之后两者进行交换。
    ②挖坑法:right去找比基准小的,放到left空出来的坑里,left去找比基准大的,放到right空出来的坑里。
    ③前后指针
    在这里插入图片描述

3.2.1 快排的优化

快排递归的次数太多了,会导致栈溢出。

  1. 三数取中法选基准
    对于基准值的选取,如果选取不当,可能导致最坏情况出现,那么可以采用三数取中法选择基准值
    第一个数 中位数 最后一个数 【选择中间大的数字为基准】
    找到中数后,和第一位位置的数进行交换,然后作为基准。
    这样就可以尽量保证是一颗均匀的二叉树
  2. 递归到小的子区间时,考虑使用插入排序
    快速排序越到后面,子区间越小,数据也越趋于有序,此时可以考虑使用插入排序提高效率,注意是对子区间进行插入排序,不是对整体进行插入排序。

3.3 快速排序(非递归——栈)

用栈去模拟递归左边和递归右边
栈用来存小区间的两端的下标
要保证小区间至少有2个元素,才把区间下标入栈
然后每次出栈2个,重新定位小区间,

 //快速排序非递归
    public static void quickSortNot(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        Deque<Integer> stack = new LinkedList<>();
        int div = partition(nums,left,right); //挖坑法
        //判断是否有2个元素
        if (left +1 < div) {
            stack.push(left);
            stack.push(div-1);
        }
        if (div + 1 < right) {
            stack.push(div+1);
            stack.push(right);
        }
        while (!stack.isEmpty()) {
            right = stack.pop();
            left = stack.pop();
            div = partition(nums,left,right);
            if (left +1 < div) {
                stack.push(left);
                stack.push(div-1);
            }
            if (div + 1 < right) {
                stack.push(div+1);
                stack.push(right);
            }
        }
    }

4. 归并类排序

4.1 二路归并排序(递归)

  1. 思路:

先两两分解,再两两合并
先将序列元素分解成为独个的,有序表中只有一个元素分解结束,再两两合并成有序的,即将已有序的子序列合并,得到完全有序的序列,先让每个子序列有序,再使子序列段间有序。

  1. 实现:
    //归并排序
    public static void mergeSort(int[] nums) {
        //先分解
        divM(nums, 0 ,nums.length-1);
    }
    //递归分解
    public static void divM(int[] nums, int left, int right) {
        if (left >= right) {
            return;
        }
        int mid = left + (right - left) / 2;
        divM(nums,left,mid);
        divM(nums,mid+1,right);
        //合并
        merge(nums,left,right,mid);
    }
    //合并
    public static void merge(int[] nums, int left, int right, int mid) {
        int s1 = left;
        int s2 = mid + 1;
        int[] tmp = new int[right - left +1]; //额外开辟的空间
        int k = 0; //tmp数组的下标
        while (s1 <= mid && s2 <= right) {
            if (nums[s1] <= nums [s2]) {
                tmp[k++] = nums[s1];
            }else {
                tmp[k++] = nums[s2];
            }
        }
        while (s1 <= mid) {
            tmp[k++] = nums[s1];
        }
        while (s2 <= right) {
            tmp[k++] = nums[s2];
        }
        //现在tmp已经有序了,但不是在原来数组上排序的
        //把tmp数组放到原数组上
        for (int i = 0; i < tmp.length; i++) {
            nums[i + left] = tmp[i];
        }
    }
  1. 分析:
    在这里插入图片描述稳定性:稳定**
    时间复杂度**:O(nlogn)
    【快排和归并都是nlogn,但还是快排的速度快,可以理解为nlogn前面有系数,快排的系数比归并小,所以快排更快】
    空间复杂度:O(n)会为临时数组开辟内存空间 int[] tmp = new int[right - left +1]; //额外开辟的空间
    对数据不敏感,任何序列都需要经过 分解+合并 两个过程

5. 基于比较的排序总结

  1. 稳定性
    只有3个排序是稳定的:插入排序、冒泡排序、归并排序
  2. 对数据不敏感
    只有3个排序对数据不敏感:选择排序、堆排序、归并排序
  3. 时间复杂度(最坏情况下)
    ①插入类排序
    直接插入排序:O(n的平方)
    希尔排序:O(n的1.3次方)【平均的,局部估计,与gap有关,分组进行插入排序】
    ②选择类排序
    选择排序:O(n的平方)
    堆排序:O(nlogn)【前提一定要先建堆】
    ③交换类排序
    冒泡排序:O(n的平方)
    快速排序:O(nlogn)【最好情况下】
    ④归并排序
    二路归并排序:O(nlogn)
    只有3个排序时间复杂度是nlogn:堆排序、快速排序、归并排序
  4. 空间复杂度
    只有2个排序的空间复杂度不是O(1):快速排序O(logn)、归并排序O(n)

6. 非比较类排序

不能比较数字之间的大小而进行的排序。

6.1 计数排序

  1. 思路:

①找到给定序列中的最小元素值和最大元素值 ②新建一个计数数组,数组的长度由第一步找到的最小值和最大值确定的范围而定
③遍历序列数组,对应计数数组的下标对其进行计数的操作 ④遍历计数数组,将计数数组中值不是0的下标对应复制到序列数组中,即排好序了

  1. 适用场景
    一组集中在某个范围的数据,因为如果不集中就会浪费计数数组的很多内存空间。
  2. 实现:
    public static void countSort(int[] nums) {
        int min = nums[0];
        int max = nums[0];
        //找最大值和最小值
        for (int i = 1; i < nums.length; i++) {
            if (min > nums[i]) {
                min = nums[i];
            }
            if (max < nums[i]) {
                max = nums[i];
            }
        }
        //新建计数数组
        int[] count = new int[max - min + 1];
        //遍历序列数组,并且用计数数组计数
        for (int i = 0; i < nums.length; i++) {
            count[nums[i] - min]++;
        }
        //遍历计数数组
        int k = 0;
        for (int i = 0; i < count.length; i++) {
            while (count[i] != 0) {
                nums[k] = i + min;
                k++;
                count[i]--;
            }
        }
    }
  1. 分析:
    稳定性:稳定**
    时间复杂度**:O(max(n,计数数组范围))
    空间复杂度:O(计数数组范围)
    注意:计数排序在数据范围集中时效率很高,但是适用范围及场景有限。
    在这里插入图片描述

6.2 基数排序

  1. 思路:

建立0到9也就是10个基数捅, 先按照个位排序,将个位放置对应的记述桶内 再依次取出 先按照使位排序,将十位放置对应的记述桶内 再依次取出
直至最高位,循环上述操作

  1. 分析:
    ①进出的次数和最大值的位数有关
    ②基数桶可以用队列来表示
    原始序列:123 99 678 93 58 77 65 54 26
    在这里插入图片描述

6.3 桶排序

  1. 思路:

划分多个范围相同的区间
每个子区间自排序
合并

  1. 分析:
    在这里插入图片描述

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

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

相关文章

管理者必备的六大复盘方法工具汇总

无论是对于企业还是个人来说&#xff0c;复盘都是一个能让我们快速成长的方法&#xff0c;尤其是项目经理和PMO&#xff0c;你是带领项目团队的&#xff0c;每一次项目的完成&#xff0c;都有很多经验&#xff0c;俗话说&#xff0c;最大的浪费是经验的浪费&#xff01;复盘的作…

基础IO-文件操作函数,文件描述符,理解缓冲区

文章目录基础IO回顾c语言的文件操作函数操作系统的文件操作函数open—打开文件write—写入文件read—读文件内容感性现象理解文件文件描述符fd文件描述符的分配规则重定向重定向函数dup2输出重定向追加重定向输入重定向再次理解文件理解缓冲区感性理解缓冲区缓冲区刷新策略写一…

新的一年,建议尝试下这7个JavaScript 库

常言道“你不必重新发明轮子”。第三方库它可以帮助您以简单的方式编写复杂且耗时的功能&#xff0c;一个好的项目应当使用一些优秀的库&#xff0c;下面我推荐下&#xff0c;在你的下个项目中&#xff0c;建议用上这7 个有用的库。1、Video.jsVideo.js 是一个基于 HTML5 的视频…

跑步用挂脖耳机好还是无线耳机、公认最好的跑步耳机推荐

蓝牙耳机近几年受到市场的欢迎&#xff0c;种类越来越多&#xff0c;各类功能也日益五花八门&#xff0c;消费者很难准确的进行分辨&#xff0c;一不小心可能买到华而不实的产品。现在了解一下值得入手的蓝牙耳机&#xff0c;从多个角度对蓝牙耳机进行评估后&#xff0c;得出以…

互联网导航系统——DNS:《流浪地球2》中重启互联网的现实解读

《流浪地球2》展现了一个浩大的宇宙级工程&#xff1a;宏大壮观的万座行星发动机、拥有超强算力的量子计算机、连接天地的太空电梯……这些“硬科技”让观众大开眼界。 电影中刘德华饰演的图恒宇能否重启互联网根服务器是拯救地球任务的关键。互联网可以重启吗&#xff1f;现实…

Array.prototype.sort()排序,升降排序使用方法

sort() 方法对数组中的元素进行适当排序并返回数组。这种情况不一定稳定。默认排序顺序根据字符串 Unicode 代码点。 目录 升序降序排序法 对象可以按照某个属性排序 const months [March, Jan, Feb, Dec] months.sort() // [Dec, Feb, Jan, March] console.log(months) // …

聊聊GC是如何快速枚举根节点的

本文已收录至Github&#xff0c;推荐阅读 &#x1f449; Java随想录 世界上最快乐的事&#xff0c;莫过于为理想而奋斗。——苏格拉底 文章目录什么是根节点枚举根节点枚举存在的问题如何解决根节点枚举的问题安全点安全区域HotSpot使用的是可达性分析算法&#xff0c;该算法需…

ssm高校大学校园租赁平台的设计与实现java

当今社会&#xff0c;信息技术发展快速。同时&#xff0c;随着生活水平提高&#xff0c;学生有了更大的购买力&#xff0c;这就使得闲置物品增多&#xff0c;校园里物品更新快&#xff0c;使用周期短。而且传统的校园租赁平台&#xff0c;已经不能够满足学生的需求。学院校园租…

人工智能识别图片食物

一、准备食物图片&#xff08;橘子和苹果&#xff09;二、识别学习关键代码编写public static void study() throws Exception {//学习Picture picture new Picture();//图片解析类 图片&#xff08;文件&#xff09;-三通道矩阵Config config new Config();//现有的环境业务…

一文了解WebSocket及Springboot集成WebSocket

文章目录WebSocket是什么WebSocket通信原理和机制WebSocket协议是什么WebSocket协议和Http协议有什么区别WebSocket常用在那些场景Springboot集成WebSocketpom依赖java相关代码configcomponenthtml代码页面访问效果WebSocket是什么 &#x1f34a;WebSocket是一种网络通信协议&…

Linux C编程

编写C代码 编辑器&#xff1a;vim&#xff0c;编写.c文件 编译 gcc 源文件 -o 生成可执行文件名 gcc -c&#xff1a;只编译&#xff0c;不链接&#xff0c;生成.o文件 make工具和Makefile文件 make工具&#xff1a;GNU make&#xff0c;是一个文件&#xff0c;用于将源代…

【CANoe示例分析】EthernetCanGW_Test_CN

1、工程路径 此示例工程来自于Vector官网:EthernetCanGW_Test_CN 感兴趣的可以自行下载! 2、示例目的 如何在CANoe中创建一个网关,实现转发以太网报文到多个CAN网络中。该使用案例是对CAN网络进行压力测试 3、示例内容 本示例通过执行Test Module里的测试用例Bus_load…

《电路/电路原理》—戴维宁(南)定理实战演练

前言战前准备什么是戴维南定理&#xff1f;戴维南定理&#xff08;Thevenins theorem&#xff09;标准解释&#xff1a;含独立电源的线性电阻单口网络N&#xff0c;就端口特性而言&#xff0c;可以等效为一个电压源和电阻串联的单口网络。电压源的电压等于单口网络在负载开路时…

CSS预处理器、移动端适配

1、预处理器概念 1.1、CSS编写的痛点 CSS作为一种样式语言, 本身用来给HTML元素添加样式是没有问题的。 但是目前前端项目已经越来越复杂, 不再是简简单单的几行CSS就可以搞定的, 我们需要几千行甚至上万行的CSS来完成页面的美化工作。 随着代码量的增加, 必然会造成很多的…

LeetCode-26. 删除有序数组中的重复项

目录题目分析双指针理解代码实现题目来源 26. 删除有序数组中的重复项 题目分析 解法&#xff1a; 双指针 首先注意数组是有序的&#xff0c;那么重复的元素一定会相邻。 要求删除重复元素&#xff0c;实际上就是将不重复的元素移到数组的左侧。 考虑用 2 个指针&#xff0c;…

拉伯证券|7900亿芯片巨头狂跌,发生了什么?

全球芯片巨子忽然爆雷。 英特尔刚刚交出了一份“十分糟糕”的财报。美东时间1月26日美股盘后&#xff0c;英特尔公布的2022第四季度及全年财报显现&#xff0c;第四季度的营收为140亿美元&#xff0c;同比大幅下降32%&#xff0c;不及商场预期&#xff1b;第四季度净亏损7亿美元…

【项目精选】基于SpringBoot和Vue开发的功能强大的图书馆系统(附源码)

功能介绍 图书馆系统功能包括&#xff1a; 1、读者端&#xff1a; 1.智能推荐图书 2.读者在线预约座位 3.读者借阅归还图书 4.图书详情 5.图书评论、评星 6.用户登录、注册、修改个人信息 7.用户自定义图书标签 8.用户报名活动参加活动 9.书架展示和添加删除 10.用户邮件登录…

Win11的两个实用技巧系列之u盘怎么设置密码?

Win11系统u盘怎么设置密码?Win11设置u盘密码的方法win11U盘怎么设置密码&#xff1f;今天小编就为大家带来了Win11设置u盘密码的方法&#xff0c;需要的朋友一起看看吧现在还是有很多用户都在使用U盘来存储一些重要的文件和数据&#xff0c;而为了更好的保护里面的安全&#x…

mongodb的索引操作

Mongodb的索引操作 学习目标 掌握 mongodb索引的创建&#xff0c;删除操作掌握 mongodb查看索引的方法掌握 mongodb创建唯一索引的方法 1. 为什么mongdb需要创建索引 加快查询速度进行数据的去重 2. mongodb创建简单的索引方法 语法&#xff1a;db.集合名.ensureIndex({属…

【手写 Promise 源码】第八篇 - 完善 Promise 并通过 promise-aplus-tests 测试

一&#xff0c;前言 上一篇&#xff0c;实现 Promise 对返回值 x 各种情况的分析和处理&#xff0c;主要涉及以下几个点&#xff1a; 回顾了相关的 Promise A 规范内容&#xff1b;根据 Promise A 规范描述和要求&#xff0c;实现了核心解析方法&#xff1a;resolvePromise&a…