十大排序算法Java实现及时间复杂度

news2024/11/17 0:26:09

文章目录

  • 十大排序算法
    • 选择排序
    • 冒泡排序
    • 插入排序
    • 希尔排序
    • 快速排序
    • 归并排序
    • 堆排序
    • 计数排序
    • 基数排序
    • 桶排序
    • 时间复杂度
  • 参考资料

十大排序算法

选择排序

  • 原理
    从待排序的数据元素中找出最小或最大的一个元素,存放在序列的起始位置,
    然后再从剩余的未排序元素中寻找最小/最大元素,放在已排序的序列的末尾,
    以此类推,直到全部待排序的数据元素的个数为零。

  • 实现方法

  1. 设置下标指针i和j,i从数组的第一个元素开始,j从(i+1)个元素开始
  2. j遍历到lens,选出最小的值min,将nums[i]与min交换;如果没有找到一个nums[j]<nums[i],说明自己本身就是最值,不交换;
  3. i++开始选取下一个元素,重复2,直到i到达lens-1出
    以数据{12,8,6,45,18}为例
  • 图示
    在这里插入图片描述

  • 代码实现

public class Sort {
    public static void main(String[] args) {
        int[] nums = {12,8,6,45,18};
        //选择排序
        selectSort(nums);
    }
    public static void selectSort(int[] nums){
        int lens = nums.length;
        int temp;
        //优化,排序之前先遍历
        boolean isSort = true;
        for(int i=0; i < lens-1; ++i){
            if(nums[i] > nums[i+1]){
                //有无序的
                isSort = false;
                break;
            }
        }
        if(isSort){
            return;//直接结束
        }
        //优化结束
        System.out.println("开始选择排序");
        for(int i=0; i< lens-1; ++i){
            for(int j=i+1;j< lens;++j){
                if(nums[j] < nums[i]){
                    temp = nums[j];
                    nums[j] = nums[i];
                    nums[i] = temp;
                }
            }
        }
        for(int i =0; i < lens; ++i){
            System.out.print(nums[i] + " ");
        }

    }

}

冒泡排序

  • 原理
    通过对排序序列从前向后(从下标较小的元素开始)依次比较相邻元素的值,若发现逆序则交换,
    使得值比较大的元素逐渐从前向后移动,就像水底下的气泡一样逐渐向上冒。

  • 实现方法

  1. 设置下标指针i和j,i用于统计外循环的次数,j用来表示当前轮次需要遍历的元素范围
  2. j的范围是0~lens-1-i,因为我们这里是每次将最大的值放在尾部,因此到第i轮的时候,最后i个值已经排完序了,不需要再判断了;
  3. 如果nums[j] > nums[j+1],则进行交换
  4. 重复上述步骤,直到lens轮排序完毕
  • 图示
    在这里插入图片描述

  • 代码

public class Sort {
    public static void main(String[] args) {
        int[] nums = {12,8,6,45,18};
        //冒泡排序
        bubbleSort(nums);
    }

    public static void bubbleSort(int[] nums){
        int lens = nums.length;
        int temp;
        System.out.println("开始冒泡排序");
        for(int i=0; i< lens - 1; ++i){
            for(int j = 0; j < lens - 1 - i; ++j){
                if(nums[j] > nums[j + 1]){
                    temp  = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = temp;
                }
            }
        }
        for(int i=0;i<lens;++i){
            System.out.print(nums[i] + " ");
        }
    }
}

插入排序

  • 原理
    将一个记录插入到有序表中,从而形成一个新的有序表;
    每一步将一个待排序的元素,按照排序码的大小,插入到前面已经排好序的一组元素的适当位置上去,直到元素全部插入为主。

  • 实现过程

  1. 每次从待排序数组中选取元素value,将其插入到有序表中
  2. 设置下标指针i和j,i指向待排序元素,j指向已排序元素尾部,并不断左移
  3. j=i-1,当j不越界并且value小于nums[j]的时候,我们要将nums[j]及其后面的数组往右边移一位,直到value大于等于nums[j]
  4. 此时j+1的位置是value应该插入的位置,将其插入进去即可
  • 图示
    在这里插入图片描述

  • 代码

public class Sort {
    public static void main(String[] args) {
        int[] nums = {12, 8, 6, 45, 18};
        insertSort(nums);
    }

    public static void insertSort(int[] nums) {
        int lens = nums.length;
        System.out.println("开始插入排序");
        for (int i = 1; i < lens; ++i) {
            int value = nums[i];
            int j;
            for (j = i - 1; j >= 0 && value < nums[j]; j--) {
                nums[j + 1] = nums[j];//挪空位
            }
            nums[j + 1] = value;
        }
        for (int i = 0; i < lens; ++i) {
            System.out.print(nums[i] + " ");
        }
    }
}

希尔排序

  • 原理
    先将整个待排序的记录序列分组,对若干子序列分别进行直接插入排序,
    随着增量逐渐减少即整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

  • 实现过程
    参考:java希尔排序

  • 代码

public class Sort {
    public static void main(String[] args) {
        int[] nums = {12, 8, 6, 45, 18};
        shellSort(nums);
    }

    public static void shellSort(int[] nums) {
        for (int gap = nums.length / 2; gap > 0; gap /= 2) {
            for (int i = gap; i < nums.length; ++i) {
                for (int j = i - gap; j >= 0; j -= gap) {
                    if (nums[j] > nums[j + gap]) {
                        int temp = nums[j];
                        nums[j] = nums[j + gap];
                        nums[j + gap] = temp;
                    }
                }
            }
        }
        System.out.println(Arrays.toString(nums));
    }
}

快速排序

  • 原理
    通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,
    然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

  • 图示
    在这里插入图片描述

  • 代码

public class Sort {
    static int[] nums = {12, 8, 6, 45, 18};

    public static void main(String[] args) {

        quickSort(nums, 0, nums.length - 1);
        System.out.println("快速排序: " + Arrays.toString(nums));
    }

    public static void quickSort(int[] nums, int low, int high) {
        int i, j, pivot;
        //结束条件
        if (low >= high) {
            return;
        }
        i = low;
        j = high;
        //选择的节点,默认选择第一位数
        pivot = nums[low];
        while (i < j) {
            //从右到左找到第一个比pivot小的数
            while (nums[j] >= pivot && i < j) {
                j--;
            }
            //从左到右找到比节点大的数
            while (nums[i] <= pivot && i < j) {
                i++;
            }
            if (i < j) {
                //循环找到后,交换
                int temp = nums[i];
                nums[i] = nums[j];
                nums[j] = temp;
            }
        }
        //一轮结束后,交换节点的数和ij相遇点的数
        nums[low] = nums[i];
        nums[i] = pivot;
        //对pivot左边和右边的数进行快速排序
        quickSort(nums, low, i - 1);
        quickSort(nums, i + 1, high);
    }
}

归并排序

  • 原理
    基于分治思想,先将待排序的数组不断拆分,直到拆分到区间里只剩下一个元素的时候。
    不断合并两个有序的子区间,直到所有区间都合并在一起,此时数组有序。

  • 实现过程

  1. 编写递归函数sortMerge(int[] nums,int left,int right);
  2. 参数nums表示要排序的数组,left和right表示当前排序的范围;
  3. 每进入一个子函数,计算mid,将待排序数组再一分为二,函数sortMerge的终止条件是left==right,即无法再拆分
  4. 回溯时要合并刚刚自己拆分的两个数组,合并的范围同样是left到right,用k表示合并后数组元素对应的下标
  5. 此时,两个子区间的合并,就说合并两个有序数组,借助临时数组temp存储还未合并的两个子数组原始的内容
  6. 有序数组1的下标用i表示,范围是[left,mid],有序数组2的下标用j表示,范围是[mid+1,right]
  7. 在i,j都未越界的情况下,选择小的存到nums[k],并将对应的指针往右移;
  8. 若i/j越界,则将j/i剩下的数据修改到nums中
  • 图示
    从数组中间拆分,每次拆成两个子区间
    在这里插入图片描述

函数的指向过程就是构造一个二叉树,红色箭头是当递归到left==right时,进行回溯
此时指向函数体里面的合成操作
在这里插入图片描述

  • 代码
public class Sort {
    public static void main(String[] args) {
        int[] nums = {6, 2, 7, 1, 9, 4, 8, 5, 12, 10};          //给定一个数组
        int len = nums.length;
        int[] temp = new int[len];
        mergeSort(nums, 0, len - 1, temp);
        System.out.println(Arrays.toString(nums)); //打印输出得到数组
    }
    private static void mergeSort(int[] nums, int left, int right, int[] temp) {
        if (left == right) {//当拆分到数组当中只要一个值的时候,结束递归
            return;
        }
        int mid = (left + right) / 2;   //找到下次要拆分的中间值
        mergeSort(nums, left, mid, temp);//记录树左边的
        mergeSort(nums, mid + 1, right, temp);//记录树右边的

        //合并两个区间
        for (int i = left; i <= right; i++) {
            temp[i] = nums[i];
            //temp就是辅助列表,新列表的需要排序的值就是从辅助列表中拿到的
        }
        int i = left;       //左子数组起点
        int j = mid + 1;  //右子数组起点
        //合并两个有序数组,成为一个新的有序数组
        for (int k = left; k <= right; k++) {//k 就为当前要插入的位置
            if (i == mid + 1) { //i到了右子数组起点,证明左子数字已经比较完毕
                nums[k] = temp[j]; //右子数字剩余的全部值赋给原数组
                j++;
            } else if (j == right + 1) { //当j超过当前的数组范围,证明右区间的数组已经遍历完毕了
                nums[k] = temp[i];//如果k还没有走完,证明左区间数据还有剩余,直接全部复制上去
                i++;
            }
            //用来比较,寻找小的哪一位插入
            else if (temp[i] <= temp[j]) { //如果左子数组最小值小于右子数组最小值
                nums[k] = temp[i]; //将两个数组中的最小值赋值给原数组
                i++;
            } else {
                nums[k] = temp[j];
                j++;
            }
        }
    }
}

堆排序

  • 原理
    堆是一种完全二叉树的数据结构,可以分为大根堆,小根堆。
    大根堆:每个结点的值都大于或者等于他的左右孩子结点的值
    小根堆:每个结点的值都小于或等于其左右孩子的结点值
    以大根堆为例,首先把待排序的元素按照大小在二叉树位置上排列,且要满足堆的特性。
    根据特性把根节点拿出来,然后再堆化下,即用父节点和他的孩子节点进行比较,取最大的孩子节点和其进行交换,
    再把根节点拿出来,一直循环到最后一个节点,就排序好了。

  • 实现过程

  1. 给定的待排序序列作为二叉树的层序遍历结果,构建二叉树
  2. 将这个二叉树构造成一个大顶堆(从最后一个非叶子结点开始,比较它的左右孩子是否比自己大,比自己大就交换,逐层往上找,最后根节点是最大值)
  3. 将堆顶元素与末尾元素进行交换,此时末尾为最大值;
  4. 将剩余n-1个元素重新构成一个堆,这样会得到n个元素的次小值。如此反复执行,便得到有序序列;
  • 图示
    在这里插入图片描述

  • 代码

public class Sort {
    static int[] nums = {4, 6, 1, 8, 9, 3, 5, 7, 11};
    public static void main(String[] args) {//给定一个数组
        heapSort(nums);
        System.out.println(Arrays.toString(nums)); //打印输出得到数组
    }

    public static void heapSort(int[] nums) {
        System.out.println("开始堆排序");
        //1.构建堆,使得nums[0]成为最大值
        buildMaxHeap(nums);
        for (int i = nums.length - 1; i >= 1; i--) {
            swap(nums, 0, i);//将当前的最大堆顶放在最后一位
            adjustHeap(nums, 0, i);//寻找次大值
        }
    }

    public static void buildMaxHeap(int[] nums) {
        for (int i = (nums.length - 1 - 1) / 2; i >= 0; i--) {
            adjustHeap(nums, i, nums.length);
        }
    }

    public static void adjustHeap(int[] nums, int i, int length) {
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        int largest = i;
        if (left < length && nums[left] > nums[i]) {
            //左结点大,修改largest下标
            largest = left;
        }
        if (right < length && nums[right] > nums[largest]) {
            //看右节点的值是否会比largest的大
            largest = right;
        }
        if (largest != i) {
            //需要交换
            swap(nums, i, largest);
            adjustHeap(nums, largest, length);//继续调整
        }
    }

    public static void swap(int[] nums, int i, int largest) {
        int temp = nums[i];
        nums[i] = nums[largest];
        nums[largest] = temp;
    }
}

计数排序

  • 原理
    将待排序元素值转换为键存储在额外开辟的数组空间中,其要求输入的数据必须是有确定范围的整数。

  • 实现过程
    以待排序元素为0~9以内整数为例
    我们创建一个长度为10的整数ans,ans[i]用于统计数字i在待排序元素中出现的次数
    之后,根据ans[i]的值,输出ans[i]次i,直到遍历完成。

  • 图示
    在这里插入图片描述

  • 代码

public class Sort {
    static int[] nums = {6, 2, 7, 1, 9, 4, 8, 5, 2, 1, 3, 2, 4, 4, 5, 6, 7};
    public static void main(String[] args) {
        int len = nums.length;
        countSort(nums);
        System.out.println(Arrays.toString(nums)); //打印输出得到数组
    }

    public static void countSort(int[] nums) {
        System.out.println("开始计数排序");
        int len = nums.length;
        int[] a = new int[10];//下标0~9
        for (int i = 0; i < len; ++i) {
            a[nums[i]]++;
        }
        int k = 0;
        for (int i = 0; i < 10; ++i) {
            for (int j = 1; j <= a[i]; j++) {
                nums[k++] = i;
            }
        }
    }
}

基数排序

  • 原理
    通过键值的部分资讯,将要排序的元素分配至某些桶中;对于一个整数数组,先按个位数从低到高进行排序,相同的放在同一个桶中;
    之后按十位数排序,再按百位数排序,直到所有数的第k位数都是0(K取决于数组中最大的元素)。
  • 实现过程
  1. 找出数组中的最大值maxNum,遍历轮次与其有关
  2. 指针div表示的是当前按哪一个键值进行排序,1,10,100,1000分别表示键值为个位,十位,百位,千位。
  3. 每一轮计算元素对应的键值,做法是 nums[i] / div % 10; 如nums[i] = 248,div = 10; nums[i]/div = 248 / 10 = 24,24 %10得到4,
  4. 将元素依次装入对应的桶中,每一轮分配完之后,将桶中的数据按顺序依次传回原数组nums中,因为下一轮遍历需要根据此顺序。
  • 图示在这里插入图片描述

  • 代码

public class Sort {
    static int[] nums = {4, 6, 1, 8, 9, 3, 5, 7, 11};
    public static void main(String[] args) {//给定一个数组
        radixSort(nums);
        System.out.println(Arrays.toString(nums)); //打印输出得到数组
    }

    public static void radixSort(int[] nums) {
        System.out.println("开始基数排序");
        //先找到最大值,知道要排序几轮
        int maxNum = Integer.MIN_VALUE;
        for (int i = 0; i < nums.length; ++i) {
            if (nums[i] > maxNum) {
                maxNum = nums[i];
            }
        }
        //创建10个桶,因为桶里面装的数据个数未知,所以用数组+list优于二维数组
        LinkedList<Integer>[] lists = new LinkedList[10];
        for (int i = 0; i < 10; ++i) {
            lists[i] = new LinkedList<>();
        }

        //开始分桶,div表示当前排序的位数,1为个位,10为十位
        for (int div = 1; div <= maxNum; div *= 10) {
            for (int i = 0; i < nums.length; ++i) {
                int num = nums[i] / div % 10;//计算其位数的值
                lists[num].offer(nums[i]);
            }
            //把桶中的数据传回nums数组
            int index = 0;
            for (LinkedList<Integer> list : lists) {
                while (!list.isEmpty()) {
                    nums[index++] = list.poll();
                }
            }
        }
    }
}

桶排序

  • 原理
    将序列中的元素分布到一定数量的桶内,然后分别对桶内的元素进行排序与,最后再将各个桶内的有序子序列放回原始序列中。
    对于桶内的元素,可以使用别的排序算法,也可以递归使用桶排序;
    一般桶内元素使用插入算法进行排序。
  • 实现过程
  1. 找出待排序的数组中的最大元素max和最小元素min
  2. 根据指定的桶数创建桶,本文使用的桶是List结构,桶里面的数据也采用List结构存储
  3. 根据公式遍历数组元素:桶编号=(数组元素-最小值)*(桶个数-1)/(最大值-最小值),把数据放到相同的桶中
  4. 从小到大遍历每一个桶,同时对也桶里的元素进行排序
  5. 把排好序的元素从索引为0开始放入,完成排序
  • 代码
public class Sort {
    static int[] nums = {4, 6, 1, 8, 9, 3, 5, 7, 11};
    public static void main(String[] args) {//给定一个数组
        bucketSort(nums, 3);
        System.out.println(Arrays.toString(nums)); //打印输出得到数组
    }

    public static void bucketSort(int[] nums, int bucketSize) {
        System.out.println("开始桶排序");
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        for (int num : nums) {
            max = Math.max(num, max);
            min = Math.min(num, min);
        }
        //创建bucketSize个桶
        List<List<Integer>> bucketList = new ArrayList<>();
        for (int i = 0; i < bucketSize; i++) {
            bucketList.add(new ArrayList<>());
        }
        //将数据放入桶中
        for (int num : nums) {
            //确定桶号:桶编号=(数组元素-最小值)*(桶个数-1)/(最大值-最小值)
            int bucketIndex = (num - min) * (bucketSize - 1) / (max - min);
            List<Integer> list = bucketList.get(bucketIndex);
            list.add(num);
        }
        //对每一个桶进行排序
        for (int i = 0, index = 0; i < bucketList.size(); ++i) {
            List<Integer> list = bucketList.get(i);
            list.sort(null);
            for (int value : list) {
                nums[index++] = value;
            }
        }
    }
}

时间复杂度

排序方法时间复杂度(平均)时间复杂度(最坏)时间复杂度(最好)空间复杂度稳定性
插入排序O(N2)O(N2)O(N)O(1)稳定
希尔排序O(N1.3)O(N2)O(N)O(1)不稳定
选择排序O(N2)O(N2)O(N2)O(1)不稳定
堆排序O(N log2 N)O(N log2 N)O(N log2 N)O(1)不稳定
冒泡排序O(N2)O(N2)O(N)O(1)稳定
快速排序O(N log2 N)O(N2)O(N log2 N)O(log2 N)不稳定
归并排序O(N log2 N)O(N log2 N)O(N log2 N)O(N)稳定
计数排序O(N+k)O(N+k)O(N+k)O(N+k)稳定
桶排序O(N+k)O(N2)O(N)O(N+k)稳定
基数排序O(N*k)O(N*k)O(N*k)O(N+k)稳定

参考资料

资料1
十大经典排序
快速排序
堆排序
堆排序(Java)
桶排序

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

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

相关文章

C# Windows 窗体控件中的边距和填充

可以将 Margin 属性、Left、Top、Right、Bottom 的每个方面设置为不同的值&#xff0c;也可以使用 All 属性将它们全部设置为相同的值。 在代码中设置Margin&#xff0c;元素的左边设置为5个单位、上边设置为10个单位、右边设置为15个单位和下边设置为20个单位。 TextBox myT…

10_10C++

X-mid #include <iostream> using namespace std; class Kun {//算术运算符friend const Kun operator(const Kun &k1,const Kun &k2);friend const Kun operator-(const Kun &k1,const Kun &k2);friend const Kun operator*(const Kun &k1,const Ku…

AI能否取代程序员:探讨人工智能在编程领域的角色

引言&#xff1a; 随着人工智能&#xff08;AI&#xff09;技术的快速发展&#xff0c;人们开始思考&#xff1a;AI是否能够取代程序员&#xff1f;这个问题引发了广泛的讨论和辩论。一些人认为&#xff0c;AI的出现将彻底改变编程的面貌&#xff0c;而另一些人则坚信&#xf…

线性代数 --- QR分解,A=QR

矩阵的QR分解&#xff0c;格拉姆施密特过程的矩阵表示 首先先简单的回顾一下Gram-Schmidt正交化过程的核心思想&#xff0c;如何把一组线性无关的向量构造成一组标准正交向量&#xff0c;即&#xff0c;如何把矩阵A变成矩阵Q的过程。 给定一组线性无关的向量a,b,c&#xff0c;我…

【深度学习】Chinese-CLIP 使用教程,图文检索,跨模态检索,零样本图片分类

代码&#xff1a;https://github.com/OFA-Sys/Chinese-CLIP/blob/master/deployment.md 文章目录 安装环境和onnx推理转换所有模型为onnx测试所有onnx模型的脚本onnx cpu方式执行docker镜像 安装环境和onnx推理 安装环境&#xff0c;下载权重放置到指定目录&#xff0c;进行on…

基于Java+SpringBoot+Vue线上医院挂号系统的设计与实现 前后端分离【Java毕业设计·文档报告·代码讲解·安装调试】

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

Swagger-go学习笔记

目录 Swagger的作用背景Swagger介绍 Swagger的基本使用1. 使用步骤2. 添加注释3. 生成接口文档数据4. 引入gin-swagger5. 测试结果6. 使用Token Swagger-go的中文文档通用API信息API操作MIME类型参数类型数据类型 Swagger的作用 背景 在传统的前端端分离的项目中&#xff0c;…

JAXB 使用记录 bean转xml xml转bean 数组 继承

JAXB 使用记录 部分内容引自 https://blog.csdn.net/gengzhy/article/details/127564536 基础介绍 JAXBContext类&#xff1a;是应用的入口&#xff0c;用于管理XML/Java绑定信息 Marshaller接口&#xff1a;将Java对象序列化为XML数据 Unmarshaller接口&#xff1a;将XML数…

数字孪生和数据分析:数字化时代的力量结合

在当今数字化时代&#xff0c;数据是无处不在的。企业、政府和个人不仅生成了大量数据&#xff0c;还寻求从中获取有价值的信息以进行更好的决策。在这个背景下&#xff0c;数字孪生和数据分析成为了迎合这一需求的两个关键概念。本文带大家一起探讨二者之间相辅相成的关系。 一…

黑马店评-04缓存更新策略,保证MySQL数据库中的数据和Redis中缓存的数据一致性

缓存更新策略(数据一致) 更新策略 缓存更新是Redis为了节约内存而设计出来的机制,当我们向Redis插入太多数据时就会导致缓存中的数据过多,所以Redis会对部分数据进行更新即淘汰 低一致性需求(数据长久不发生变化): 使用内存淘汰机制,例如店铺类型信息的查询缓存,因为这部分…

day02_运算符_if

零、今日内容 1.运算符 2.scanner 3.if,ifelse,elseif 复习 学习方法: 睡觉前过电影(1jdk,配置环境变量2idea使用3HelloWorld程序解释 4变量5数据类型6String) 主方法是每次都要写的,因为代码要执行(psvm) 输出语句每次都要写的,因为要看结果(sout) 1.声明变量的语法格式 数据类…

网络安全(黑客)—0基础学习手册

目录梗概 一、自学网络安全学习的误区和陷阱 二、学习网络安全的一些前期准备 三、网络安全学习路线 四、学习资料的推荐 想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01; 网络安全可以基于攻击和防御视角来…

Git【入门】从安装到会用(千字总结●超详细)

我的个人主页&#xff1a;☆光之梦☆_C语言基础语法&#xff08;超详细&#xff09;,【java入门】语法总结-CSDN博客 创作不易&#xff0c;如果能帮到你就好 注&#xff1a;你的 &#x1f44d;点赞 ⭐收藏 &#x1f4dd;评论 是对博主最大的支持与鼓励喔 认真看完这篇文章&am…

极智AI | 能够轻松构建大模型端到端应用的LangChain 到底是什么

欢迎关注我的公众号 [极智视界],获取我的更多经验分享 大家好,我是极智视界,本文来介绍一下 能够轻松构建大模型端到端应用的 LangChain,到底是什么。 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码下载,链接:https://t.zsxq.com/0aiNxERDq 先上官…

Cesium热力图

二、代码 <!doctype html> <html><head><meta charset"utf-8"><link rel"stylesheet" href"./css/common.css"><title>热力图</title><script src"./js/config.js"></script>…

手动实现SpringMVC底层机制

手动实现SpringMVC底层机制 &#x1f41f;准备工作&#x1f34d;搭建SpringMVC底层机制开发环境 实现任务阶段一&#x1f34d;开发ZzwDispatcherServlet&#x1f966;说明: 编写ZzwDispatcherServlet充当原生的DispatcherServlet(即核心控制器)&#x1f966;分析代码实现&#…

基于点标签的目标检测与计数深度学习框架盘点

(1)P2PNet <1>P2PNet提出 论文出处&#xff1a;Rethinking Counting and Localization in Crowds: A Purely Point-Based Framework 论文链接&#xff1a;https://arxiv.org/abs/2107.12746 开源代码&#xff1a;https://github.com/TencentYoutuResearch/CrowdCount…

物联网AI MicroPython传感器学习 之 MQ136硫化氢传感器

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; 一、产品简介 MQ136 是一种硫化氢检测传感器&#xff0c;感应范围为 1 - 200ppm。传感元件是 SnO2&#xff0c;它在清洁空气中的电导率较低。当存在 H₂S 气体时&#xff0c;传感器的电导率随着气体浓度的升…

Gralloc ION DMABUF in Camera Display

目录 Background knowledge Introduction ia pa va and memory addressing Memory Addressing Page Frame Management Memory area management DMA IOVA and IOMMU Introduce DMABUF What is DMABUF DMABUF 关键概念 DMABUF APIS –The Exporter DMABUF APIS –The…

PyTorch模型的多种导出方式提供给其他程序使用

PyTorch模型的多种导出方式提供给其他程序使用 flyfish PyTorch模型的多种导出方式 PyTorch模型的多种导出方式提供给其他程序使用1 模型可视化2 预训练模型3 ONNX模型导出有输入有输出TRAINING导出方式EVAL导出方式 4 自定义输入输出的名字&#xff0c;并可批量推理5 导出JI…