常见排序算法思路总结与性能分析

本文详细介绍了冒泡排序、插入排序、选择排序、希尔排序、快速排序和归并排序的思路与性能分析。冒泡排序和插入排序是稳定的排序算法,而选择排序和快速排序则是不稳定的。在时间复杂度上,快速排序和归并排序最优、最坏和平均情况均为O(nlogn),而冒泡排序、插入排序和选择排序在最坏情况下为O(n^2)。
摘要由CSDN通过智能技术生成

在这里插入图片描述

1. 冒泡排序

1.1 冒泡排序思路

每次循环,从数组第一个元素开始,对数组内的元素两两比较,若array[i]>array[i+1] 则元素交换并向后遍历,经过一轮遍历之后最大值移动到了数组尾部。经过 n-1 轮循环即可完成排序。

public void BubbleSort(int[] array,int n){
    if(n<=1) return;
    //外层循环n-1次
    for(int i=0;i<n-1;i++){
        for(int j=0;j<n-i-1;j++){
            if(array[j]>array[j+1]){
                int tmp = array[j];
                array[j] = array[j+1];
                array[j+1] =tmp;
            }
        }
    }
}

1.2 优化思路

在上面的分析中,在数组元素完全有序之前,每一轮都会做元素的交换。也即是说,当我们进行到某一轮循环,整个过程中没有出现元素的交换,表明数组已经完全有序了,即可以终止外层循环。

 public void BubbleSort2(int[] array,int n){
     if(n<=1) return;
     int flag = 1;
     //外层循环n-1次
     for(int i=0;i<n-1;i++){
         if(flag==0) break;
         flag = 0;
         for(int j=0;j<n-i-1;j++){
             if(array[j]>array[j+1]){
                 int tmp = array[j];
                 array[j] = array[j+1];
                 array[j+1] =tmp;
                 flag = 1;
             }
         }
     }
 }

1.3 算法性能分析

  • 时间复杂度分析
    • 最好情况时间复杂度:对于冒泡排序的最好情况是数组元素完全有序,如 1,2,3,4,5,此时基于优化的冒泡排序只需要遍历一次,因此最好时间复杂度为O(n)。
    • 最坏情况时间复杂度:最坏情况是数组元素完全逆序,如5,4,3,2,1,那么需要执行n-1次循环,每个内层循环中第一次执行n-1个操作,第二次执行n-2个操作,最后一次执行1个操作;总的操作数为 1+2+3+…+(n-1) = n(n-1)/2个操作。另外说明完全逆序情况下每个操作中均包含了比较和交换。因此最坏时间复杂度为 O ( n 2 ) O(n^2) O(n2)
    • 平均时间复杂度:在上文的分析中我们发现“交换”操作是数组元素从无序到有序的必然步骤,对于完全有序的数组交换次数为0次,完全逆序的数组交换次数为n(n-1)/2次,那么平均状态下的数组交换次数为n(n-1)/4次。此外还有比较次数,比较次数大于交换次数,同时小于完全逆序的比较次数n(n-1)/4。因此平均时间复杂度为 O ( n 2 ) O(n^2) O(n2)
  • 空间复杂度分析
    • 冒泡排序属于原地排序算法。所谓原地排序算法,是指不需要申请多余的存储空间,在自身数组中通过交换和比较完成排序的算法。因此原地排序算法空间复杂度为O(1)。
  • 稳定性分析
    • 所谓稳定,是指在原有排序数据中存在相同数值的时候,经过排序后相同数值的元素相对次序仍然不变。对于冒泡排序,我们只要在遇到相同数值元素的时候不经过交换,即可保持算法稳定性。因此冒泡排序属于稳定性算法。

2. 插入算法

2.1 插入算法思路

插入算法是把一个数组分为两部分,前面部分是已排序的部分,后面部分是未排序的部分。每次循环是从未排序部分取出第一个元素,插入到已排序部分中。

 public void insertionSort(int[] array,int n){
     if(n<=1) return;
     int i,j;

     for(i=1;i<n;i++){
         int tmp = array[i];
         for(j=i-1;j>=0;j--){
             if(array[j]>tmp)
                 array[j+1]=array[j];
             else
                 break;
         }
         array[j+1] = tmp;
     }
 }

2.2 算法性能分析

  • 时间复杂度分析
    • 最好情况时间复杂度:最好情况即数组元素完全有序,每次循环仅进行了一次元素比较,不涉及到元素移动。循环执行了n-1 次,因此时间复杂度为O(n)。
    • 最坏情况时间复杂度:最坏情况是数组元素完全逆序,每次循环都要进行元素的比较和移动;且第一次循环执行一个操作,第二次执行2个操作,…,第n-1次执行n-1个操作。总的操作数为(n-1) = n(n-1)/2个操作。因此时间复杂度为 O ( n 2 ) O(n^2) O(n2)
    • 平均情况时间复杂度:在冒泡排序中分析平均情况时间复杂度时,我们介绍到数组序列的有序度是和交换次数等价的,然后我们拿平均情况下的交换次数来代表平均有序度的数组序列。在插入算法中,没有直接的元素交换操作,而是元素移动操作。同样的,完全有序的数组移动次数为0,完全逆序的数组移动次数为 n(n-1)/2,那么平均状态下的数组移动次数为n(n-1)/4次。因此时间复杂度也为 O ( n 2 ) O(n^2) O(n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值