常见排序算法-冒泡排序、选择排序 、插入排序 、快速排序、 归并排序 、堆排序

简介: 排序算法• 冒泡排序• 冒泡排序的优化• 选择排序• 插入排序• 快速排序• 归并排序• 堆排序

冒泡排序


145866746f6f4a6ab7348bed9c731daa.gif

平均时间复杂度: o(n^2)

最好时间: o(n)

最坏时间: o(n^2)

空间复杂度: o(1)

是否稳定: 稳定

简单的冒泡排序

    public int[] bubbleSort(int [] nums){
        int len = nums.length;
        if(len <= 1) return nums;
        for(int i = 0;i < len;i++){
            for(int j = 0;j < len-i-1;j++){
                if(nums[j] > nums[j+1]){
                    int temp = nums[j+1];
                    nums[j+1] = nums[j];
                    nums[j] = temp;
                }
            }
        }
        return nums;
    }


冒泡排序的优化

设置标志位

设置一个标志位来标识这次遍历是否进行过交换

如果没有进行过交换则表示数组已经有序,直接退出

 public int[] binarySort(int [] nums){
        int len = nums.length;
        if(len <= 1) return nums;
        for(int i = 0;i < len-1;i++){
            boolean isSort = true;  //是否有序
            for(int j = 0;j < len-i-1;j++){
                if(nums[j] > nums[j+1]){
                    int temp = nums[j+1];
                    nums[j+1] = nums[j];
                    nums[j] = temp;
                    isSort = false;
                }
            }
            if(isSort) break;
        }
        return nums;
    }


设置结束位置

比如初始数组为[4,3,2,1,5,6]

经过第一次排序后数组变为[3,2,1,4,5,6]

如果按照普通冒泡排序下次需要遍历的下标范围为[0,4]

但是[3,4]是已经有序的,所以可以减少比较,保存上次交换的结束位置

public int[] bubbleSort(int [] nums){
    int len = nums.length;
    if(len <= 1) return nums;
    int max_index = len-1;
    int index = max_index;
    for(int i = 0;i < len-1;i++){
        boolean isSort = true;  //是否有序
        for(int j = 0;j < index;j++){
            if(nums[j] > nums[j+1]){
                int temp = nums[j+1];
                nums[j+1] = nums[j];
                nums[j] = temp;
                isSort = false;
                max_index=j;
            }
        }
        if(isSort) break;
        index = max_index;
    }
    return nums;
    }

双向冒泡排序

与设置结束位置类似,这个是也设置了起始位置

使得在left之前的都是已经排好序的

    public int[] bubbleSort(int [] nums){
        int len = nums.length;
        if(len <= 1) return nums;
        int left = 0;
        int right = len-1;
        int tleft = 0,tright = 0;
        while(left < right){
            boolean isSort = true;
            for(int i = left;i < right;i++){
                if(nums[i+1] < nums[i]){
                    int temp = nums[i];
                    nums[i] = nums[i+1];
                    nums[i+1] = temp;
                    isSort = false;
                    tright = i;
                }
            }
            if(isSort)break;
            right = tright;
            isSort = true;
            for(int i = right;i > left;i--){
                if(nums[i] < nums[i-1]){
                    int temp = nums[i];
                    nums[i] = nums[i-1];
                    nums[i-1] = temp;
                    isSort = false;
                    tleft = i;
                }
            }
            if(isSort)break;
            left = tleft;
        }
        return nums;
    }

选择排序


fd3b383f48e74e8e86067846af27c12b.gif

平均时间复杂度: o(n^2)

最好时间: o(n^2)

最坏时间: o(n^2)

空间复杂度: o(1)

是否稳定: 不稳定

选择排序

    public int[] selectSort(int [] nums){
        int len = nums.length;
        if(len <= 1) return nums;
        for(int i = 0;i < len;i++){
            int minIndex = i;
            for(int j = i;j < len;j++){
                if(nums[j] < nums[minIndex]){
                    minIndex = j;
                }
            }
            int t = nums[minIndex];
            nums[minIndex] = nums[i];
            nums[i] = t;
        }
        return nums;
    }


插入排序


7a7a54d942f74bfdb4b0629173d24c0c.gif

平均时间复杂度: o(n^2)

最好时间: o(n)

最坏时间: o(n^2)

空间复杂度: o(1)

是否稳定: 稳定

插入排序

    public int[] insertSort(int [] nums){
        int len = nums.length;
        if(len <= 1) return nums;
        for(int i = 1;i < len;i++){
            int cur = nums[i];
            int preIndex = i - 1;
            while(preIndex >= 0 && nums[preIndex] > cur){
                nums[preIndex+1] = nums[preIndex];
                preIndex--;
            }
            nums[preIndex+1] = cur;
        }
        return nums;
    }


快速排序


e34b13dd820448efb8f6664e5b1192dd.gif

平均时间复杂度: o(nlogn)

最好时间: o(nlogn)

最坏时间: o(n^2)

空间复杂度: o(logn)

是否稳定: 不稳定

快速排序

    public void quickSort(int [] nums,int left,int right){
       if(left >= right) return;
       int l = left - 1;
       int r = right + 1;
       int t = nums[left];
       while(l < r){
           do l++;while(nums[l] < t);
           do r--;while(nums[r] > t);
           if(l < r){
               int temp = nums[l];
               nums[l] = nums[r];
               nums[r] = temp;
           }
       } 
       quickSort(nums,left,r);
       quickSort(nums,r+1,right);
    }


归并排序


73d0a113dfc94817850eb68e93437e94.gif

平均时间复杂度: o(nlogn)

最好时间: o(nlogn)

最坏时间: o(nlogn)

空间复杂度: o(n)

是否稳定: 稳定

    public void mergeSort(int [] nums,int left,int right){
        if(left >= right) return;
        int mid = left + right >> 1;
        mergeSort(nums,left,mid);
        mergeSort(nums,mid+1,right);
        //需要合并 [left,mid] [mid+1,right]
        int []temp = new int[right-left+1];
        int l = left,r = mid+1,k = 0;
        while(l <= mid && r <= right){
            if(nums[l] < nums[r]) temp[k++] = nums[l++];
            else temp[k++] = nums[r++];
        }
        while(l <= mid) temp[k++] = nums[l++];
        while(r <= right) temp[k++] = nums[r++];
        for(int i = right;i >= left;i--){
            nums[i] = temp[--k];
        }
    }


堆排序


22b96ad4c2174e4e8f6bfc5f47cecd6a.gif

平均时间复杂度: o(nlogn)

最好时间: o(nlogn)

最坏时间: o(nlogn)

空间复杂度: o(1)

是否稳定: 不稳定

    public void heapSort(int [] nums){
        int len = nums.length;
        if(len <= 1) return;
        //构造大根堆
        for(int i = (len-1)/2; i>=0 ;i--){
            heap(nums,i,len);
        }
        //将根弄到最后
        for(int i = len-1;i >=0; i--){
            int t = nums[0];
            nums[0] = nums[i];
            nums[i] = t;
            heap(nums,0,i);
        }
    }
    //子树构建大顶堆
    public void heap(int[] nums,int index,int size){
        int max = index;
        int left = 2 * index + 1;
        int right = 2 * index + 2;
        if(left < size && nums[left] > nums[max]) max = left;
        if(right < size && nums[right] > nums[max]) max = right;
        if(max != index){
            int t = nums[index];
            nums[index] = nums[max];
            nums[max] = t;
            heap(nums,max,size);
        }
    }
相关文章
|
2天前
|
搜索推荐 C语言
【排序算法】快速排序升级版--三路快排详解 + 实现(c语言)
本文介绍了快速排序的升级版——三路快排。传统快速排序在处理大量相同元素时效率较低,而三路快排通过将数组分为三部分(小于、等于、大于基准值)来优化这一问题。文章详细讲解了三路快排的实现步骤,并提供了完整的代码示例。
17 4
|
17天前
|
搜索推荐
冒泡排序算法
【10月更文挑战第19天】冒泡排序是一种基础的排序算法,虽然在实际应用中可能不是最优的选择,但对于理解排序算法的基本原理和过程具有重要意义。
|
1月前
|
算法 搜索推荐 Shell
数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
18 1
|
1月前
|
算法 搜索推荐
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
本文介绍了冒泡排序、选择排序和插入排序三种基础排序算法的原理、实现代码和测试结果。
16 0
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
|
30天前
|
搜索推荐 C语言
排序算法--冒泡排序
排序算法--冒泡排序
13 0
|
1月前
|
存储 搜索推荐 算法
【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析
【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析
|
19天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
4天前
|
算法 数据挖掘 数据安全/隐私保护
基于FCM模糊聚类算法的图像分割matlab仿真
本项目展示了基于模糊C均值(FCM)算法的图像分割技术。算法运行效果良好,无水印。使用MATLAB 2022a开发,提供完整代码及中文注释,附带操作步骤视频。FCM算法通过隶属度矩阵和聚类中心矩阵实现图像分割,适用于灰度和彩色图像,广泛应用于医学影像、遥感图像等领域。
|
5天前
|
算法 调度
基于遗传模拟退火混合优化算法的车间作业最优调度matlab仿真,输出甘特图
车间作业调度问题(JSSP)通过遗传算法(GA)和模拟退火算法(SA)优化多个作业在并行工作中心上的加工顺序和时间,以最小化总完成时间和机器闲置时间。MATLAB2022a版本运行测试,展示了有效性和可行性。核心程序采用作业列表表示法,结合遗传操作和模拟退火过程,提高算法性能。
|
6天前
|
存储 算法 决策智能
基于免疫算法的TSP问题求解matlab仿真
旅行商问题(TSP)是一个经典的组合优化问题,目标是寻找经过每个城市恰好一次并返回起点的最短回路。本文介绍了一种基于免疫算法(IA)的解决方案,该算法模拟生物免疫系统的运作机制,通过克隆选择、变异和免疫记忆等步骤,有效解决了TSP问题。程序使用MATLAB 2022a版本运行,展示了良好的优化效果。
下一篇
无影云桌面