十大排序算法(绝对口语化的概念理解)

目录

一、前言

二、交换类排序(!!!重点!!!)

   2.1、冒泡排序(Bubble Sort)

   2.2、快速排序(Quick Sort)

 三、插入类排序

   3.1、直接插入排序

   3.2 、希尔排序

四、选择类排序

   4.1 、简单选择排序

   4.2、堆排序

五、归并排序

六、基数排序


一、前言

           排序,是数据处理过程中经常使用的一种重要操作。

           排序:是把一个 无序的 数据序列 按照某个关键字进行 有序排列的过程。

           最常见的排序分类:

 本篇文章 注重的是  概念理解;如果有需要代码实现,可以去看  博客园博主   一像素  的作品,下面给出链接。

                                                  想看代码实现的 点击


二、交换类排序(!!!重点!!!)

           交换类排序有分为:

  •             冒泡排序
  •             快速排序  (面试官 最喜欢问的一种 排序方法)

      2.1、冒泡排序(Bubble Sort)

                 冒泡排序:是一种简单的交换类排序。

       原理

  • -比较相邻的元素。如果第一个比第二个大,就交换他们两个。(升序,降序反之)
  • - 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后      的元素应该会是最大的数。
  • - 针对所有的元素重复以上的步骤,除了最后一个。
  • - 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。


        口诀:

升序排列: N个数字来排队 两两相比靠前, 外层 循环length-1 内层循环length-i-1

降序排序: N个数字来排队 两两相比靠前, 外层 循环length-1 内层循环length-i-1


     代码实现(java):

package com.kaikeba.demo1;

public class test {
    public static void main(String[] args) {
        int[] nums = {1,3,9,5,6,7,15,4,8};
        int temp;
        // 首先进行 冒泡排序
        for (int i=0; i<nums.length-1; i++) {      //第一层循环
            for (int j = 0; j < nums.length - i - 1; j++) {    //第二层循环
                if (nums[j] > nums[j + 1]) {
                    temp = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = temp;
                }
            }
            for (int k=0; k< nums.length;k++){  //打印每一次  第二层循环 结束后,nums数组
                System.out.print(nums[k]+"\t");
            }
            System.out.println("");
        }
    }
}


2.2、快速排序(Quick Sort)

         快速排序算法,是由图灵奖获得者 Tony Hoare 于1962年设计出来的。

                                  是同量数级中最快的内部排序方法。

                                  是冒泡排序的升级算法

         原理:

  •   从序列中,任选一个元素(通常选取第一个元素)作为支点,其余元素逐一与之比较;
  •   比该元素小的,则交换到该元素前面;     比该元素大的,则交换到该元素后面;
  •   在进行一轮循环之后,支点前面的元素(称序列1),都是比ta小的;支点后面的元素称序列2),都是比ta大的。 但是 两个序列1、2,各自之间还是无序的。
  •   然后,对两个序列,重新执行上述操


动图不能理解该算法,可以看下面举的例子。

   原排列 :{37,19,90,64,13,49,20,40}

  第一躺排序结果: {20   19   13}    37    {64  49  90  40}

  第二躺排序结果: {13   19}   20   {37}   {40  49}  64  {90}

  第三趟排序结果:  13   {19}  20   37     40   {49}    64   90

  最终                   : 13  19  20   37  40  49  64  90


代码实现(java)

      代码这块,博主后面,会自己编写,继续更新........

 三、插入类排序

     插入类排序分为:

  •     直接插入排序
  •     希尔排序

    3.1、直接插入排序

          直接插入排序,是最简单的排序方法之一。

          原理:

  • 将待排序的数列,分为无序部分 && 有序部分。开始时,第一个元素为有序区其余元素则为无序区
  • 之后,将无序区 的第一个元素,按序插入有序区。
  • 重复上述操作,直到无序区中全部元素插入有序区。


动图不能理解该算法,可以看下面这个例子:  

   " [   ] "  表示有序区 ;      高亮元素表示无序区第一个元素

     每一次 都将无序区的 第一个元素,插入有序区中,并按序排好

   待排序序列:    20   6   15    7     3     6

  开始排序前:    [ 20 ]   6   15  7   3   6   

   第一次排序:   [ 6    20 ]   15   7   3   6 

   第二次排序:   [ 6    15   20 ]    7   3   6

   第三次排序:   [ 6   7   15   20 ]    3    6

   第四次排序:   [ 3   6   7   15  20 ]    6

   第五次排序:   [ 3  6   6  7   15   20  ]



3.2 、希尔排序

         希尔排序:

                 由D.L.Shell 在1959年提出得名,又称 “ 缩小增量排序算法 ”。

                 希尔排序对 直接插入排序进行了改进

        原理:

  •   增量序列:t1,t2,…,tk,其中tk=1
  •   根据给定的增量序列,依次按增量值分成若干小组,然后这小组进行直接插入排序。进行下一次按增量值排序。        
  •   经过上述几次分组排序后,整个序列就 “基本有序”了,此时增量值为1也就是进行一次直接插入排序。


 动图不能理解该算法,可以看下面这个例子:  

    增量序列 [ 5,3,1],                 初始序列: 47  55  10  80  15  5  30  70  47  40

    相同颜色,表示根据增量值分组,分到同一组。  ! 即同颜色的 为一组  !

                    第一个增量值:5

序号:0123456789
按增量值分组:4755108015530704740

同组的进行

直接插入排序

的结果

 5 30 10 4715 47 55708040

                    第二个增量值:3

序号:0123456789
按增量值分组:5301047154755708040

同组的进行

直接插入排序

的结果

5151040304747708055

                  第三个增量值:1

序号:0123456789
按增量值分组:5151040304747708055

同组的进行

直接插入排序

的结果

 5101530404747557080

四、选择类排序

          选择类排序分为:

  •            简单选择排序
  •            堆排序

   4.1 简单选择排序

             简单选择排序,又称直接选择排序;是一种简单直观的排序方法。

             原理:

  •             从待排序 序列中,选取最小的元素,与序列第一个元素交换。
  •             然后,再选取除上述元素外的 最小元素,与序列第二个元素交换。
  •             依次进行,直到排序完成。


动图不能理解该算法,可以看下面这个例子:  

  •     待排序 序列:  23    90   9   25   16
  •     红色元素 表示:当前序列最小元素,
  •     绿色表示,已排好序 的元素
  •     每次操作:红色元素与   “交换位置”   的元素交换
序号:01234
初始序列:239092516

选取最小值

和 交换位置

交换

位置

min
序号:01234
第一次交换结果:990232516

选取最小值

和 交换位置

交换

位置

min
序号:01234
第二次交换结果:916232590

选取最小值

和 交换位置

min

交换

位置

序号:01234
第三次交换结果:916232590

选取最小值

和 交换位置

min

交换

位置

序号:01234
第四次交换结果:916232590


4.2、堆排序

          堆排序:由Floyd与Williams,于1964年共同提出的  对 简单选择排序进行改进 的一种算法。

          原理:

  •          将待排序的的序列,构建成一个大顶堆,最大元素则为 堆顶的根节点。
  •          将根节点元素 与 末尾元素 交换。
  •          然后剩下元素,再构建一个新的大顶堆。
  •          然后重复上述操作。

         难题:

  1.  如何构建初始堆?
  2. 输出堆顶元素后,如何构建新的大顶堆?
  •        先将待排序 序列,依序按照完全二叉树,构建好一个完全二叉树,为后面建成大顶堆做准备。
  •        大顶堆构建:因为只有一个结点的树必是堆,而在完全二叉树中,所有大于(n/2)的结点,都是叶子,就都是堆。建堆时,是从(n/2)结点为跟的子树开始 构建出该节点的大顶堆。(从n/2开始往前 筛选)


例子:

 待排序序列: 36  24  48  12  65  25  43  59 76 34   (共10个元素,即n=10)

  •  完全二叉树构建如下图所示:


  •   然 后开始 构建大顶堆,从(n/2)开始,也就是第五个元素 “65”开始 构建大顶堆。

             !!!!! 如上图所述,初始堆构建完成!!!! 



 下一步,堆顶元素与末尾元素 交换,并把交换后的 末尾元素(即原本的堆顶元素,也就是序列的最大值)拿出去。


       在上一步,输出最大元素后,可以看到现在 根节点是 34,我们下一步则开始调整二叉树,使其又变成 大顶堆。

       其实,到这一步了,还是比较简单的,仔细看一下上面的二叉树,不难发现,现在就只有根节点,不满足 大顶堆的条件。

       所以,只要把 34 与 65 调换,调换之后,根节点65就满足了 大顶堆条件。但34的子树,又不满足了。

      因此又要继续调换,把 59 与 34 调换。虽然步骤多了点,但其实还是很简单的,小伙伴们仔细看,就行。

        如上图为调整后的 ,一个新的 大顶堆,一样的操作,根节点与末尾结点交换,并输出根节点65,为原序列第二大元素。

     后续,就依次重复操作,不断调整 大顶堆,直至输出所有元素!!!

五、归并排序

       归并:在数据结构中的定义是    将两个或两个以上的 有序表 组合成一个新的 有序表。

       归并排序:是建立在归并操作上的一种有效的排序算法。

        归并排序分类:

  •              二路归并排序
  •              多路归并排序

   本篇文章,就介绍   二路归并排序:

      原理: 

  •     将待排序序列的每一个元素,看作一个有序的 序列。
  •     将序列两两合并成一个 有序的 序列;若总共有奇数个序列,则最后那个序列,保持            不变,等前面的序列 两两合并之后,一起进入下一步操作。
  •     两两合并之后,会得到新的 有序序列,这些新的序列,再一次两两合并。
  •     重复上述操作,直至只剩下一个序列

例子:

   待排序 序列 :   23   52  67  6  18    10              【】:表示一个有序的 序列

      相同颜色 :表示  待会    两两合并

   开始时 :               【23】    【52】   【67】   【6】   【18】   【10】

相邻的两两合并:    【23  52】    【6     67】    【10   18】

相邻的两两合并:    【6   23   52   67】    【10   18】

最终合并:               【6  10   18   23   52   67】

六、基数排序

           基数排序:是一种典型的分配类排序方法。

                             主要是对有多个关键字的元素进行排序的。

         例如,可以把整数的 个位、十位、百位作为关键字,对元素进行排序。

 例子:  369   367   167  239  237   138   230   139

第一步,获取个位 的取值范围:  0 7 8 9,

              然后按照 序列的顺序  ,依次分配到 下面中去:

  0  :230

  7  :367    167    237

  8  :138

  9  :369    239    139

    所以第一次 排序结果为:    230   367   167   237  138  369  239  139


第二步 ,获取 十位的取值范围:  3     6

  3  :  230    237   138  239   139

  6  :  367   167     369   

  所以第二次 排序结果为:   230  237  138  239  139  367  167  369


第三步,获取 百位的取值范围:

   1: 138   139   167 

   2: 230   237   239 

   3:  367  369

所以第二次 排序结果为: 138  139  167  230  237  239  367  369

    好了,本篇文章,博主就介绍这么多,一共8种排序方法,大家重点掌握好冒泡排序和快速排序。如果文章有误或者不足之处,欢迎指正奥,博主会虚心听取的。最后制作不易,希望小伙伴们可以多点赞、多评论,关注一下博主哟!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新计划

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值