Java基本排序总结(Sort)

什么是排序

排序的定义

对一序列对象根据某个关键字进行排序(通俗点来说就是吧一堆数据按照从小到大(升序),或者从大到小排列(降序)),我们下面都基于升序来讲解。

排序的相关术语

  • 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面
  • 不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面
  • 内排序:所有排序操作都在内存中完成
  • 外排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行
  • 时间复杂度: 一个算法执行所耗费的时间
  • 空间复杂度:运行完一个程序所需内存的大小

排序的分类

在这里插入图片描述

算法分析

在这里插入图片描述

冒泡排序

冒泡排序bulleSort)这里就不在多说了,非常经典的一种排序,我们接触的第一种排序啦。

算法描述:

  • 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
  • 从头到尾两两元素进行比较交换 ,这时尾部元素为最大元素
  • 针对所有的元素重复以上的步骤,除了最后一个
  • 重复步骤1~3,直到排序完成

算法分析
时间复杂度:

  • 当数据有序时 最好 O(n)
  • 当数据无序时 最差 O(n2)

空间复杂度O(1)
不稳定

实现代码

    public static void bullSort(int[] array){
   
        for(int i=0;i<array.length;i++)
        {
   
            int flag=0;
            for(int j=0;j<array.length-1-i;j++)
            {
   
                if(array[j]>array[j+1])
                {
   
                    int tmp=array[j];
                    array[j]=array[j+1];
                    array[j+1]=tmp;
                    flag=1;
                }
            }
            if(flag==0)
            {
   
                break;
            }
        }
    }

选择排序

选择排序(selectSort)是一种简单直观的排序算法。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
算法描述

  1. 先将第一个元素开始,将第一个元素与后面的每一个元素进行比较,如果比其小,则进行交换,直到数组遍历完,第一个元素便是最小的元素
  2. 接着从第二个元素开始,与第二个元素之后的元素进行比较
  3. 重复上述过程

算法分析
时间复杂度:

  • 当数据有序时 最好 O(n)
  • 当数据无序时 最差 O(n2)

空间复杂度O(1)
稳定
实现代码

    public static void selectSort(int[] array) {
   
         for(int i=0;i<array.length-1;i++)
         {
   
             for(int j=i+1;j<array.length;j++)
             {
   
                 if(array[j]<array[i])
                 {
   
                     int tmp=array[i];
                     array[i]=array[j];
                     array[j]=tmp;
                 }
             }
         }
    }

希尔排序

希尔排序shellSort)也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,它与插入排序的不同之处在于,它会优先比较距离较远的元素(将小的数据尽可能的放到前面)希尔排序是把数据按照增量数组中得值分成好多个组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的数据越来越多,当增量减至1时,整个数据恰被分成一组,其实此时也就是插入排序了。(增量数组当中的值为素数,但最后一个是1)
算法描述

  1. 选择一个增量序列drr[]
  2. 从增量序列中取出第一个k,对序列进行分组,并对进行每组进行插入排序
  3. 选择增量序列中的下一个,重复2步骤

算法分析
算法分析
时间复杂度:

  • 最好 O(n1.5)
  • 最坏 O(n2)

空间复杂度O(1)
不稳定

实现代码

    public static void shellSort(int[] array) {
   
        int[] drr = {
   5,3,1};//增量数组
        for (int i = 0; i < drr.length; i++) {
   
            shell(array,drr[i]);
        }
    }
    
    public static void shell(int[] array ,int gap) {
   
      int j,tmp;
      for(int i=gap;i<array.length;i++)
      {
   
          tmp=array[i];
          j=i-gap;
          for(;j>=0;j-=gap)
          {
   
              if(array[j]>tmp)
              {
   
                  array[j+gap]=array[j];
              }else{
   
                  break;
              }
          }
          array[j+gap]=tmp;
        }
    }
    
   

举例数组为[12,5,9,16,6,8,27,58,80,0,7,4,33,55,77]
增量序列为[5,3,1]

  • 分五组

在这里插入图片描述

  • 每组进行插入排序

在这里插入图片描述

  • 在分三组,在进行插入排序

在这里插入图片描述

归并排序

归并排序mergeSort)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。(原理-合并两个有序数组
在这里插入图片描述

算法描述
来分析一下吧,对于归并算法,有两个部分组成,分解和合并。首先讲讲分解,我们需要将待排序的序列不停地进行分解,通过两个索引变量控制,一个初始索引(low),一个结尾索引(high)。只有当两索引重合才结束分解。接下来是合并,合并操作也是最麻烦的,也是通过两个索引变量s1,s2。开始s1在左边序列的第一个位置,s2在右边序列的第一个位置,然后就是寻找左右两个序列中的最小值(合并两个数组),放到新序列中,这时可能会出现一边的元素都放置完毕了,而另外一边还存在元素,此时只需将剩余的元素按顺序放进新序列即可,因为这时左右两边的序列已经是有序的了,最后将新序列复制到旧序列。这里也特别需要注意,因为合并的过程是分步的,而并非一次合并完成,所以数组的索引是在不断变化的。(所以需要加strat保证位置的正确性)

算法分析
时间复杂度:

  • 最好:O(nlogn)
  • 最坏:O(nlogn)

空间复杂度 O(n)
稳定
实现代码

  • 递归实现
    public static void mergeSort(int[] array)
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值