`

五大基础排序算法

阅读更多

选择排序

假如我们现在要排序的数组为[3,1,0,2,8,4,2]。那么选择排序的排序流程为:

  1. 在这个数组中找出最小值与第一个元素交换,现在数组为[0,1,3,2,8,4,2]
  2. 在这个数组中除了第一个位置的元素外找出最小值与第二个元素交换,因为第二个元素就是最小的所以此次没有发生变化。现在数组为[0,1,3,2,8,4,2]
  3. 在这个数组中除了第一个、第二个位置的元素外找出最小值与第三个元素交换,现在数组为[0,1,2,3,8,4,2]
  4. 在这个数组中除了第一个、第二个、第三个位置的元素外找出最小值与第四个元素交换,现在数组为[0,1,2,2,8,4,3]
  5. 在这个数组中除了第一个、第二个、第三个、第四个位置的元素外找出最小值与第五个元素交换,现在数组为[0,1,2,2,3,4,8]
  6. 在这个数组中除了第一个、第二个、第三个、第四个、第五个位置的元素外找出最小值与第六个个元素交换,因为第六个元素就是最小的所以此次没有发生变化。现在数组为[0,1,2,2,3,4,8]

现在整个数组是不是已经变得有序了呢。接下来我们看图解版本
1
接下来上代码

<figure class="highlight arduino"><table><tr> <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td> <td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">int</span> i; <span class="comment">// 有序区的末尾位置</span></span><br><span class="line"><span class="keyword">int</span> j; <span class="comment">// 无序区的起始位置</span></span><br><span class="line"><span class="keyword">int</span> <span class="built_in">min</span>; <span class="comment">// 无序区中最小元素位置</span></span><br><span class="line"><span class="keyword">int</span> []a=<span class="keyword">new</span> <span class="keyword">int</span>[]{<span class="number">3</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">2</span>,<span class="number">8</span>,<span class="number">4</span>,<span class="number">2</span>};</span><br><span class="line"></span><br><span class="line"><span class="built_in">for</span>(i=<span class="number">0</span>,n=a.length; i&lt;n; i++) {</span><br><span class="line"> <span class="built_in">min</span>=i;</span><br><span class="line"> <span class="comment">// 找出"a[i+1] ... a[n]"之间的最小元素,并赋值给min。</span></span><br><span class="line"> <span class="built_in">for</span>(j=i+<span class="number">1</span>; j&lt;n; j++) {</span><br><span class="line"> <span class="built_in">if</span>(a[j] &lt; a[<span class="built_in">min</span>])</span><br><span class="line"> <span class="built_in">min</span>=j;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 若min!=i,则交换 a[i] 和 a[min]。</span></span><br><span class="line"> <span class="comment">// 交换之后,保证了a[0] ... a[i] 之间的元素是有序的。</span></span><br><span class="line"> <span class="built_in">if</span>(<span class="built_in">min</span> != i) {</span><br><span class="line"> <span class="keyword">int</span> tmp = a[i];</span><br><span class="line"> a[i] = a[<span class="built_in">min</span>];</span><br><span class="line"> a[<span class="built_in">min</span>] = tmp;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td> </tr></table></figure>

插入排序

相信大家都有打扑克的经历,那么我们今天的插入排序就以拿牌为例开始讲(注意只是举例,不是按打牌的规则哦)

  1. 我们拿到了一张牌3,我们把它放手里,现在手里有牌[3]
  2. 我们拿到了一张牌1,拿它与手里最后一张牌也就是3比较,发现1比3小,所以我们把它插入到3的前面,现在手里有牌[1,3]
  3. 我们拿到了一张牌0,拿它与手里最后一张牌也就是3比较,发现0比3小,所以我们把它插入到3的前面,接着与3的上一张比较发现0比1还小,那么就把0在插入到1的前面,现在手里有牌[0,1,3]
  4. 我们拿到了一张牌2,拿它与手里最后一张牌也就是3比较,发现2比3小,所以我们把它插入到3的前面,接着与3的上一张比较发现2比1大,那么就不需要动了,现在手里有牌[0,1,2,3]
  5. 我们拿到了一张牌8,拿它与手里最后一张牌也就是3比较,8比3大,那么就不需要动了,现在手里有牌[0,1,2,3,8]
  6. 。。。

现在你明白什么叫做插入排序了么?如果你不明白的话也没关系,我还专门画了一张图:
2

接下来上代码

<figure class="highlight dart"><table><tr> <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td> <td class="code"><pre><span class="line"></span><br><span class="line"><span class="built_in">int</span> []<span class="built_in">num</span>=<span class="keyword">new</span> <span class="built_in">int</span>[]{<span class="number">3</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">2</span>,<span class="number">8</span>,<span class="number">4</span>,<span class="number">2</span>};</span><br><span class="line"><span class="keyword">for</span> (<span class="built_in">int</span> i=<span class="number">1</span>,n=<span class="built_in">num</span>.length;i&lt;n;i++){</span><br><span class="line"> <span class="keyword">if</span>(<span class="built_in">num</span>[i]&lt;<span class="built_in">num</span>[i<span class="number">-1</span>]){</span><br><span class="line"> <span class="keyword">for</span> (<span class="built_in">int</span> j=i;j&gt;<span class="number">0</span>;j--){</span><br><span class="line"> <span class="keyword">if</span>(<span class="built_in">num</span>[j]&lt;<span class="built_in">num</span>[j<span class="number">-1</span>]){</span><br><span class="line"> <span class="built_in">int</span> temp=<span class="built_in">num</span>[j];</span><br><span class="line"> <span class="built_in">num</span>[j]=<span class="built_in">num</span>[j<span class="number">-1</span>];</span><br><span class="line"> <span class="built_in">num</span>[j<span class="number">-1</span>]=temp;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">for</span> (<span class="built_in">int</span> i:<span class="built_in">num</span>){</span><br><span class="line"> System.out.<span class="built_in">print</span>(i+<span class="string">","</span>);</span><br><span class="line">}</span><br></pre></td> </tr></table></figure>

快速排序

快速排序是一个运用了分治法和递归算法的排序方式。假如我们现在要排序的数组为[3,1,0,2,8,4,2]。那么在进行快速排序的时候我们先要进行一些准备:

  • n作为一个数组中的标杆,一趟排序过后我们要把数组中所有大于n的数放在它的右边,所有小于n的放在它的左边。一般情况下我们会取数组第一个元素作为n,在此数组中就是n=3
  • i我们使用i来找数组中大于标杆的值,i初始指向数组第一个位置
  • j我们使用j来找数组中小于标杆的值,j初始指向数组最后一个位置

下面开始排序:

  1. 先从数组右边开始,我们发现j指向的元素2比标杆n小,那么我们将j指向的元素赋值给i指向的元素,停止操作。此时数组为[2,1,0,2,8,4,2],i指向第一个位置,j仍指向最后一个。
  2. 从数组左边开始,i指向的元素2比标杆小,所以不做操作,使i++,i指向的元素1比标杆小,所以不做操作,使i++,一直到i指向8的时候比标杆大(注意此处如果等于的话也要操作),那么就把i指向的元素赋值给j指向的元素,此时数组为[2,1,0,2,8,4,8],i指向第五个位置。也就是元素8,j仍然指向最后一个位置。
  3. 继续从右边操作,j指向的8不比n小,所以不做操作,j–,4不比3小,不做操作,j–。现在i和j的位置重合了,把n放到这个位置上。我们此轮的操作也就结束了
  4. 接下来我们把3所在的位置左边分为一个数组,右边位置分为一个数组再次进行刚才的操作。(此处就是一个递归调用了)
    接下来就来看一个图片描述的过程
    3

希尔排序

希尔排序呢,其实可以理解为插入算法排序的一个升级版了.
回忆一下当使用插入排序在进行排序数据量非常大的数据时,有一个很小的数据出现在了数组的最后,那么我们就要移动了这个数据前面所有的元素给它放置到合适的元素。例如:我们要排序的数组为[1,2,3,4,5,6,7,。。。此处省略一百万。。.,0]
相信大家肯定不喜欢这个0往前移动一百万此吧,希尔排序的出现其实就是为了解决这个问题的
希尔排序使用了分治算法,先把整个大的数组根据某个增量分为若干个组,先对这若干个组进行一个调整,保证大部分小的数据会被调整到前面来。到最后再次进行插入排序,这样就大大加快了效率了。
来一个例子,如图所示,我们要排序的数组为[3, 1, 0, 2, 8, 4, 2,6,9,1,3,-2,8],
4

  • 上方图片所说的增量就是我们进行分组的依据了。我们在这里初始值取得是数组得2分之一(此值没有标准的定义,只需保证大于1且小于数组长度即可),而红线所指向得就是我们根据这个增量所分的组了,我们分别针对每组进行排序。
  • 可以在增量为3的结果种看到,第一组3,2,8 变为了2,3,8、第二组第三组没变、第四组变为了1,2、第五组变为了3,8、第六组变为了-2,4.
  • 接下来增量减半,我们的数组分为3组,分别进行排序。
  • 现在增量值经过再次减半后已经变为1了,我们可以通过观察数组发现,在数组的后面基本不可能出现最小的数据了,现在对数组进行插入排序的效率已经非常高了

不知道现在的你明白希尔排序了么?来看一看代码吧

<figure class="highlight cpp"><table><tr> <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td> <td class="code"><pre><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">shellSort</span><span class="params">(<span class="keyword">int</span> <span class="built_in">list</span>[], <span class="keyword">int</span> length)</span></span>{</span><br><span class="line"> <span class="keyword">int</span> gap,i,j,temp;</span><br><span class="line"> <span class="keyword">for</span> (gap = length/<span class="number">2</span>; gap &gt; <span class="number">0</span>; gap /= <span class="number">2</span>){</span><br><span class="line"> <span class="keyword">for</span>(i = gap; i &lt; length; i++){</span><br><span class="line"> <span class="keyword">for</span>(j = i-gap; j&gt;=<span class="number">0</span> &amp;&amp; <span class="built_in">list</span>[j]&gt;<span class="built_in">list</span>[j+gap]; j -= gap){</span><br><span class="line"> temp = <span class="built_in">list</span>[j];</span><br><span class="line"> <span class="built_in">list</span>[j] = <span class="built_in">list</span>[j+gap];</span><br><span class="line"> <span class="built_in">list</span>[j+gap] = temp;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td> </tr></table></figure>

冒泡排序

冒泡排序在排序算法中效率算最慢的一类了,但是因为它简单的缘故仍然是工作1-3年的程序员面试经常会碰到的算法问题。
假如我们现在要排序的数组为[3,1,0,2,8,4,2]

  1. 第一轮排序为比较3和1,发现3比1大,那么我们就交换3和1,数组变成了[1,3,0,2,8,4,2]
  2. 比较3和0,发现3比0大,那么我们就交换3和0,数组变成了[1,0,3,2,8,4,2]
  3. 比较3和2,发现3比2大,那么我们就交换3和2,数组变成了[1,0,2,3,8,4,2]
  4. 比较3和8,发现3没有8大,那么不操作,数组还是[1,0,2,3,8,4,2]
  5. 比较8和4,发现8比4大,那么我们就交换8和4,数组变成了[1,0,2,3,4,8,2]
  6. 比较8和2,发现8比2大,那么我们就交换8和2,数组变成了[1,0,2,3,4,2,8]
  7. 现在第一轮的排序已经完成了,我们就筛选出来了最大值8,此时数字8已经在数组最后的位置了,下一轮排序我们就可以排除它了。第二轮排序为:比较1和0,发现1比0大,那么我们就交换1和0,数组变成了[0,1,2,3,4,2,8]
  8. 比较1和2,发现1没有2大,那么不操作,数组还是[0,1,2,3,4,2,8]
  9. 比较2和3,发现2没有3大,那么不操作,数组还是[0,1,2,3,4,2,8]
  10. 比较3和4,发现3没有4大,那么不操作,数组还是[0,1,2,3,4,2,8]
  11. 比较4和2,发现4比2大,那么我们就交换4和2,数组变成了[0,1,2,3,2,4,8]
  12. 现在第二轮排序完成了,数组最后的4和8是不是已经有序了呢
    聪明的你是不是已经发现了冒泡排序的规律了呢,代码实现:
<figure class="highlight arduino"><table><tr> <td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td> <td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">int</span> []a=<span class="keyword">new</span> <span class="keyword">int</span>[]{<span class="number">3</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">2</span>,<span class="number">8</span>,<span class="number">4</span>,<span class="number">2</span>};</span><br><span class="line"><span class="keyword">int</span> i,j;</span><br><span class="line"><span class="keyword">int</span> flag; <span class="comment">// 标记</span></span><br><span class="line"><span class="built_in">for</span> (i=a.length<span class="number">-1</span>; i&gt;<span class="number">0</span>; i--) {</span><br><span class="line"> flag = <span class="number">0</span>; <span class="comment">// 初始化标记为0</span></span><br><span class="line"> <span class="comment">// 将a[0...i]中最大的数据放在末尾</span></span><br><span class="line"> <span class="built_in">for</span> (j=<span class="number">0</span>; j&lt;i; j++) {</span><br><span class="line"> <span class="built_in">if</span> (a[j] &gt; a[j+<span class="number">1</span>]) {</span><br><span class="line"> <span class="comment">// 交换a[j]和a[j+1]</span></span><br><span class="line"> <span class="keyword">int</span> tmp = a[j];</span><br><span class="line"> a[j] = a[j+<span class="number">1</span>];</span><br><span class="line"> a[j+<span class="number">1</span>] = tmp;</span><br><span class="line"> flag = <span class="number">1</span>; <span class="comment">// 若发生交换,则设标记为1</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="built_in">if</span> (flag==<span class="number">0</span>)</span><br><span class="line"> <span class="built_in">break</span>; <span class="comment">// 若没发生交换,则说明数列已有序。</span></span><br><span class="line">}</span><br><span class="line"><span class="built_in">for</span> (<span class="keyword">int</span> ii:a){</span><br><span class="line"> System.out.<span class="built_in">print</span>(ii+<span class="string">","</span>);</span><br><span class="line">}</span><br></pre></td> </tr></table></figure>

本文源码可见https://github.com/shiyujun/syj-study-demo

推荐阅读

  1. SpringCloud学习系列汇总
  2. 为什么一线大厂面试必问redis,有啥好问的?
  3. 多线程面试必备基础知识汇总
  4. Java集合源码分析汇总-JDK1.8
  5. Linux常用命令速查-汇总篇
  6. JVM系列文章汇总
  7. MySQL系列文章汇总
  8. RabbitMQ系列文章汇总

博客所有文章首发于公众号《Java学习录》转载请保留
扫码关注公众号即可领取2000GJava学习资源

1

0
0
分享到:
评论

相关推荐

    5大排序算法

    本篇文章将详细探讨五种主要的排序算法:插入排序、归并排序、堆排序、快速排序以及基数排序。 **插入排序** 插入排序是一种简单直观的排序算法,它的工作原理类似于我们手动排序一副扑克牌。算法分为两个阶段:...

    python五大排序-五大排序算法(Python),算法数据结构

    本文将详细讲解Python中的五大排序算法:冒泡排序、选择排序、插入排序、归并排序和快速排序。 1. 冒泡排序: 冒泡排序是一种基础的排序算法,其原理是通过不断比较相邻元素并交换位置来实现排序。在每一轮遍历中,...

    五大基本排序算法,算法数据结构(01)

    本文将详细介绍五大基本排序算法,包括选择排序、冒泡排序和快速排序,这些都是数据结构和算法领域中的基础知识。 1. **选择排序**: - **原理**:选择排序的基本思想是在每一轮排序中,找到未排序部分中最小(或...

    五种排序算法

    对于程序员来说,理解这些基础的排序算法不仅仅是应付面试的需要,更是进行复杂数据处理、性能优化和软件开发中的必备技能。通过这些算法的学习和应用,可以加深对算法思想的理解,提高解决实际问题的能力。

    8大排序算法

    "8大排序算法" 在计算机科学中,排序算法是一种基本的算法,能够高效地对大量数据进行排序。在本文中,我们将介绍8种常用的排序算法,包括插入排序、交换排序、选择排序、归并排序和分配排序等。 一、插入排序 ...

    基础五大排序算法(冒泡+排序+插入+希尔+快速)简述,算法数据结构

    基础五大排序算法是计算机科学中数据处理的基本方法,它们分别是冒泡排序、选择排序、插入排序、希尔排序和快速排序。这些算法都是用来对一组数据进行排序,使得数据按照特定的顺序排列,如升序或降序。 1. **冒泡...

    八大排序算法

    ### 八大排序算法精讲 #### 一、概述 排序算法是计算机科学中的一个重要组成部分,主要用于对数据进行整理和优化。根据数据处理的方式不同,排序可以分为内部排序和外部排序两大类。内部排序指的是所有待排序的数据...

    Matlab实现五大排序算法(冒泡、插入、选择、合并、快速)

    在编程领域,排序算法是数据处理中的基础,它用于对一系列元素进行有序排列。Matlab作为一款强大的数学计算和编程环境,提供了丰富的功能来实现各种排序算法。本篇将详细介绍在Matlab中实现的五种经典排序算法:冒泡...

    常见经典排序算法(C语言)1希尔排序 二分插入法 直接插入法 带哨兵的直接排序法 冒泡排序 选择排序 快速排序 堆排序.docx

    常见的经典排序算法有希尔排序、二分插入法、直接插入法、带哨兵的直接排序法、冒泡排序、选择排序、快速排序、堆排序等。 一、希尔排序(Shell 排序法) 希尔排序法,又称宿小增量排序,是 1959 年由 D.L.Shell ...

    五大排序的算法与实例

    在IT领域,排序算法是数据结构与算法设计中的基础且重要的组成部分,它们被广泛应用于数据库、搜索引擎、数据挖掘等场景,对于提升数据处理效率具有关键作用。本文将深入解析五种经典的排序算法:冒泡排序、选择排序...

    算法排序实验报告 包括对五种排序算法的算法实现时间的比较

    这篇实验报告主要关注了五种不同的排序算法:冒泡排序、插入排序、选择排序、归并排序和快速排序。在报告中,作者通过C++编程实现了这些算法,并进行了实际的性能比较,特别是在处理不同规模(N=1000, 10000, 100000...

    八大经典排序算法总结和源代码

    八大经典排序算法总结和源代码 在计算机科学中,排序算法是最基本也是最重要的算法之一。排序算法的性能直接影响到整个系统的性能。今天,我们将总结八大经典排序算法,并提供C++实现的源代码。 一、稳定排序和...

    排序算法总结文档

    这里我们主要探讨五种经典的排序算法:选择排序、冒泡排序、插入排序、快速排序以及归并排序。 1. **选择排序**: 选择排序的工作原理是通过n-1轮比较,每次找出未排序部分中的最小(或最大)元素,将其放到已排序...

    五大基本排序算法,算法数据结构(02)

    ### 五大基本排序算法 #### 一、选择排序 **基本原理:** 选择排序是一种简单直观的比较排序算法。其工作原理如下: 1. **初始化:**从数组的第一个元素开始,将其视为当前最小值。 2. **遍历:**从当前元素开始...

    排序算法 sort 经典

    排序算法和查找算法是计算机科学的基础,理解并熟练掌握各种算法对于提升程序效率和解决实际问题具有重要意义。在“array_sort”这个主题中,我们可以进一步研究如何针对数组数据结构实现高效的排序和查找操作,以...

    算法与数据结构的排序算法

    良好的排序算法能够极大地提高数据处理的效率,尤其是在大数据量的情况下,高效的排序算法对于性能优化至关重要。 二、排序算法的分类 1. 冒泡排序:这是一种简单的交换排序,通过重复遍历待排序的序列,依次比较...

    排序算法的PPT文档

    这篇PPT深入浅出地介绍了排序算法的原理、类型、评价标准以及具体实现,对于教学和实践都有极大的参考价值。 首先,我们需要理解排序的目的和方式。排序的主要目的是为了构造数据之间的关系,比如通过年龄、姓名或...

    数据结构课程设计五——排序算法综合分析.doc

    HeapSort 函数实现了堆排序算法,通过将待排序的记录构建成一个大顶堆,然后对堆进行排序来实现排序。MergeSort 函数实现了归并法排序算法,通过将待排序的记录分成若干部分,然后对每部分进行排序,最后将已排序的...

Global site tag (gtag.js) - Google Analytics