码迷,mamicode.com
首页 > 编程语言 > 详细

常用排序算法

时间:2016-05-13 23:05:37      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:

本篇给大家介绍几种软件工程中常用的排序算法

1. 插入排序

插入排序的基本思想就是:每次将一个待排序的记录,按其关键字大小插入到前面已经排序好的序列中,直到全部记录插入完成为止。

对于插入排序的概念以及其原理大家可以参考《排序算法的学习之路——插入排序(概念篇)》

插入排序细分可以分成三种情况。

直接插入排序——《排序算法学习之路——直接插入排序》

折半插入排序——《排序算法学习之路——折半插入排序》

表插入排序 ——《排序算法学习之路——表插入排序》

2. 希尔排序

希尔排序是按照该算法的设计者的名字希尔 命名的,其产生是希尔在插入排序的基础上改进的,可以说是一种特殊的插入排序。

下面先介绍一下插入排序的性质:

首先,插入排序算法对于已经有序的数据进行操作的时候,效率很高,可以达到线性排序的效率。

其次,插入排序进行排序的时候,每一趟排序只能移动一个数据。所以说这样的排序方法相对来说效率又比较低。

基于此性质,希尔排序的设计者发明了希尔排序算法,其基本思想是:

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,分割子序列的方法就是设定一个增量,待当下的每个子序列有序的时候,将增量减一半(除 以2,取整),再次进行子序列的排序。依次进行,待整个序列中的记录基本上有序的时候,再对全体记录进行依次直接插入排序,此时增量减为1,因为直接插入 排序在元素基本有序的情况下(根据上述第一点,接近最好的情况),效率是很高的。

具体实现大家可参考《排序算法学习之路——希尔排序》

3. 归并排序

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一 个有序表,称为二路归并。

归并排序最常用的实现方式是借助递归函数来实现,当然递归函数底层借助的也是栈的机制。所以说实现归并排序的方法也可以使用栈而不使用递归。

具体实大家可参考《排序算法学习之路——归并排序》《排序算法学习之路——归并排序(非递归实现)》

4. 快速排序

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序n个项目要Ο(nlogn)次比较。在最坏状况下则需要Ο(n2)次比较,但这 种状况并不常见。事实上,快速排序通常明显比其他Ο(nlogn)算法更快,因为它的内部循环(innerloop)可以在大部分的架构上很有效 率地被实现出来。

快速排序使用分治法(Divideandconquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
其实现步骤如下

1、从数列中挑出一个元素,称为“基准”(这个基准的找出方式有很多,在这里我们就默认使用第一个元素作为基准)
2、重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
3、从第二步中得到的基准的中间位置将数组分成两部分,递归地(recursive)把小于基准值元素的子序列和大于基准值元素的子序列排序。
4、重复第二步,直到子序列的数值个数为1

同样的其常用的实现方式是使用递归函数来实现。所以说也可以使用非递归的方式也就是借助栈来实现。

具体实现大家可以参考《排序算法学习之路——快速排序》《排序算法学习之路————快速排序(非递归实现)》

5. 堆排序

堆排序(Heapsort):是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

从上面的定义的最后一句话中我们同样可以得出两个概念——大顶堆、小顶堆。

所谓大顶堆就是子节点的键值或索引总是小于它的父节点。通过大顶堆得出的序列是递增的。

所谓小顶堆就是子节点的键值或索引总是大于它的父节点。通过小顶堆得出的序列是递减的。

下面我们来看一下堆排序的思想

利用小顶堆堆顶记录的是最大关键字这一特性,使得每次从无序中选择最大记录变得简单。

其基本思想为(大顶堆): 1)将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区; 2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足R[1,2...n- 1]<=R[n]; 3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元 素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。 操作过程如下: 1)初始化堆:将R[1..n]构造为堆; 2)将当前无序区的堆顶元素R[1]同该区间的最后一个记录交换,然后将新的无序区调整为新的堆。 因此对于堆排序,最重要的两个操作就是构造初始堆和调整堆,其实构造初始堆事实上也是调整堆的过程,只不过构造初始堆是对所有的非叶节点都进行调整。

具体步骤和实现大家可以参考《排序算法学习之路——堆排序》

6. 选择排序

选择排序是一种简单直观的排序算法。其基本思想是在未排序的序列中选择一个最大(或最小)元素放到末尾(注意:这里是未排序序列的末尾,可以认为是有序序列的起始位置)。

其实现步骤如下

1)首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
2)再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
3)重复第二步,直到所有元素均排序完毕。

详细介绍和代码实现大家可以参考《排序算法学习之路——选择排序》

7. 冒泡排序

冒泡排序也是一种简单直观的排序算法。其思想是:它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

冒泡排序的步骤

 

1)比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
3)针对所有的元素重复以上的步骤,除了最后一个。
4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

详细介绍和代码实现大家可以参考《排序算法学习之路——冒泡排序》

上面就是本人在学习排序算法中学习的算法,当然这些并不完整。后续会持续更新算法,希望大家持续关注。

常用排序算法

标签:

原文地址:http://www.cnblogs.com/ljty2015/p/5491245.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!