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

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

冒泡排序


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);
        }
    }
相关文章
|
6天前
|
搜索推荐 算法 Java
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
该博客文章通过UML类图和Java源码示例,展示了如何使用适配器模式将QuickSort类和BinarySearch类的排序和查找功能适配到DataOperation接口中,实现算法的解耦和复用。
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
|
5天前
|
搜索推荐 算法 Java
经典排序算法之-----选择排序(Java实现)
这篇文章通过Java代码示例详细解释了选择排序算法的实现过程,包括算法的基本思想、核心代码、辅助函数以及测试结果,展示了如何通过选择排序对数组进行升序排列。
经典排序算法之-----选择排序(Java实现)
|
5天前
|
搜索推荐 Java
经典排序算法---冒泡排序
这篇文章详细介绍了冒泡排序算法的基本思想、比较轮数和次数,并提供了Java语言实现冒泡排序的代码示例,展示了如何通过相邻元素的比较和交换来达到排序的目的。
经典排序算法---冒泡排序
|
4天前
|
算法 搜索推荐
算法设计 (分治法应用实验报告)基于分治法的合并排序、快速排序、最近对问题
这篇文章是关于分治法应用的实验报告,详细介绍了如何利用分治法实现合并排序和快速排序算法,并探讨了使用分治法解决二维平面上的最近对问题的方法,包括伪代码、源代码实现及时间效率分析,并附有运行结果和小结。
|
1月前
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
【7月更文挑战第12天】归并排序是高效稳定的排序算法,采用分治策略。Python 实现包括递归地分割数组及合并已排序部分。示例代码展示了如何将 `[12, 11, 13, 5, 6]` 分割并归并成有序数组 `[5, 6, 11, 12, 13]`。虽然 $O(n log n)$ 时间复杂度优秀,但需额外空间,适合大规模数据排序。对于小规模数据,可考虑其他算法。**
57 4
|
1月前
|
算法 搜索推荐 编译器
算法高手养成记:Python快速排序的深度优化与实战案例分析
【7月更文挑战第11天】快速排序是编程基础,以O(n log n)时间复杂度和原址排序著称。其核心是“分而治之”,通过选择基准元素分割数组并递归排序两部分。优化包括:选择中位数作基准、尾递归优化、小数组用简单排序。以下是一个考虑优化的Python实现片段,展示了随机基准选择。通过实践和优化,能提升算法技能。**
32 3
|
6天前
|
算法
基于模糊控制算法的倒立摆控制系统matlab仿真
本项目构建了一个基于模糊控制算法的倒立摆控制系统,利用MATLAB 2022a实现了从不稳定到稳定状态的转变,并输出了相应的动画和收敛过程。模糊控制器通过对小车位置与摆的角度误差及其变化量进行模糊化处理,依据预设的模糊规则库进行模糊推理并最终去模糊化为精确的控制量,成功地使倒立摆维持在直立位置。该方法无需精确数学模型,适用于处理系统的非线性和不确定性。
基于模糊控制算法的倒立摆控制系统matlab仿真
|
5天前
|
机器学习/深度学习 算法 定位技术
MATLAB - 遗传算法(GA)求解旅行商问题(TSP)
MATLAB - 遗传算法(GA)求解旅行商问题(TSP)
11 3
|
6天前
|
算法
基于多路径路由的全局感知网络流量分配优化算法matlab仿真
本文提出一种全局感知网络流量分配优化算法,针对现代网络中多路径路由的需求,旨在均衡分配流量、减轻拥塞并提升吞吐量。算法基于网络模型G(N, M),包含N节点与M连接,并考虑K种不同优先级的流量。通过迭代调整每种流量在各路径上的分配比例,依据带宽利用率um=Σ(xm,k * dk) / cm来优化网络性能,确保高优先级流量的有效传输同时最大化利用网络资源。算法设定收敛条件以避免陷入局部最优解。
|
1月前
|
传感器 算法
基于无线传感器网络的MCKP-MMF算法matlab仿真
MCKP-MMF算法是一种启发式流量估计方法,用于寻找无线传感器网络的局部最优解。它从最小配置开始,逐步优化部分解,调整访问点的状态。算法处理访问点的动态影响半径,根据带宽需求调整,以避免拥塞。在MATLAB 2022a中进行了仿真,显示了访问点半径请求变化和代价函数随时间的演变。算法分两阶段:慢启动阶段识别瓶颈并重设半径,随后进入周期性调整阶段,追求最大最小公平性。
基于无线传感器网络的MCKP-MMF算法matlab仿真

热门文章

最新文章