赞
踩
这篇文章主要讨论各种常见的排序算法,包括冒泡排序、插入排序、选择排序、快速排序、堆排序、希尔排序、归并排序、基数排序等。每种排序算法都有它自己的特点。本文将对这些算法的工作原理、特点、时间复杂度等方面进行介绍,并且给出实现示例。
一:基本定义
冒泡排序(Bubble Sort):是一种简单的排序算法,它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。
插入排序(Insertion Sort):是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
选择排序(Selection Sort):是一种简单直观的排序算法,它的工作原理是在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
快速排序(Quick Sort):是一种分治算法,它将一个数组(列表)分成两个分区,将比基准值小的放在左边,比基准值大的放在右边,然后对左右两个分区重复上述操作,直到整个列表有序。
堆排序(Heap Sort):是一种树形选择排序,其原理是将待排序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点,然后将其与末尾元素进行交换,此时末尾元素就是最大值,然后将剩余n-1个元素重新构造成一个堆,这样就会得到n个元素中的次小值,如此反复执行,便能得到一个有序序列。
希尔排序(Shell Sort):也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,它是直接插入排序算法的一种变种。
归并排序(Merge Sort):使用分治法,将大问题分解成小问题,然后通过递归的方式不断细分,最后将排序好的子序列合并成一个有序序列。
基数排序(Radix Sort):是一种基于分配式排序的非比较型整数排序,其原理是将整数按位数分组,然后按每个位数分别比较,最后按位数由低到高连接起来。
二.具体操作步骤及举例如下:
冒泡排序:是一种交换排序,它的基本思想是相邻两个数进行比较,若前者比后者大,则将两者调换位置。假设有5个数(3,2,5,1,4),将他们依次由小到大排序的过程如下:
Step 1:将3和2进行比较,因为3比2大,将3和2的位置调换,得到序列(2,3,5,1,4)。
Step 2:将3和5进行比较,因为3比5小,不需要调换,得到序列(2,3,5,1,4)。
Step 3:将5和1进行比较,因为5比1大,将5和1的位置调换,得到序列(2,3,1,5,4)。
Step 4:将5和4进行比较,因为5比4大,将5和4的位置调换,得到序列(2,3,1,4,5)。
此时,数据序列从小到大已经排好,排序结束。
插入排序:将一组未排序的数据按照其关键字的大小,通过比较和交换的方式,依次插入到已排序列中。假设有5个数(3,2,5,1,4),将他们依次由小到大排序的过程如下:
Step1:将3和2进行比较,因为3比2大,将3插入到2之后,得到序列(2,3,5,1,4)。
Step2:将3和5进行比较,因为3比5小,不需要调换,得到序列(2,3,5,1,4)。
Step3:将5和1进行比较,因为5比1大,将1插入到5之前,得到序列(2,3,1,5,4)。
Step4:将5和4进行比较,因为5比4大,将4插入到5之前,得到序列(2,3,1,4,5)。
此时,数据序列从小到大已经排好,排序结束。
选择排序:在未排序的数据中,选择出最小或最大的元素,放到数据序列的首位,然后再从剩余的数据中选择最小或最大的元素放到序列的次位,直到所有数据排序完毕。假设有5个数(3,2,5,1,4),将他们依次由小到大排序的过程如下:
Step 1:从未排序数据中选择出最小的数1,放到数据序列的首位,得到序列(1,3,2,5,4)。
Step 2:从剩余数据中选择出最小的数2,放到数据序列的次位,得到序列(1,2,3,5,4)。
Step 3:从剩余数据中选择出最小的数3,放到数据序列的次位,得到序列(1,2,3,5,4)。
Step 4:从剩余数据中选择出最小的数4,放到数据序列的次位,得到序列(1,2,3,4,5)。
此时,数据序列从小到大已经排好,排序结束。
快速排序:快速排序是一种分治法,它采用了两个步骤:分割和排序。首先,从数组中选择中间元素作为分割元素,然后以该元素为基准将数组划分为较小的部分和较大的部分。然后,对这两部分再次进行上述操作,直到数组只剩下一个元素时,即得到有序数组。 举例:假设数组为[5,2,4,1,3],选择分割元素5,数组分割为[2,4,1,3]和[5],继续将左边数组分割,此时数组分割为[2],[1,3], [4] 和 [5],继续将左边数组分割,分割为[2]和[1,3],继续将左边的数组分割,分割为[1]和[3],最后得到有序数组[1,2,3,4,5].
堆排序:堆排序也是一种分治法,通过构建最大/最小堆结构排序的一种思想。它的步骤是:首先,从无序数组构建最大/最小堆;second,将堆顶元素与堆底元素交换;third,破坏原堆,并调整堆,重新构建最大/最小堆;最后,重复第二步,直到得到有序数组。 举例:假设数组为[5,2,4,1,3],构建最大堆后,数组为[5,2,4,1,3],将堆顶元素5和堆底元素3交换,数组变为[3,2,4,1,5],破坏原堆,并调整堆,构建最大堆,此时数组变为[4,2,3,1,5],重复第二步,最后得到有序数组[1,2,3,4,5].
希尔排序:希尔排序是一种插入排序,它采用了一个“步长”来分组数据进行排序。希尔排序的步骤是:首先计算步长;然后将数组按照步长划分为子数组;接着,对每个子数组使用插入排序;最后,重复上述步骤,直到步长减小到1,即得到有序数组。 举例:假设数组为[5,2,4,1,3],步长为5/2=2,数组按照步长划分为[5,2]、[4,1]、[3]三个子数组,分别使用插入排序,得到[2,5]、[1,4]、[3],步长减小为2/2=1,数组按照步长划分为[2,5]、[1,4]、[3]三个子数组,使用插入排序,得到[1, 2, 3, 4, 5],最后得到有序数组。
归并排序:归并排序是一种分治法,它采用了两个步骤:分解和合并。首先,将大数组递归地分解为较小的两个子数组;然后,将两个子数组使用插入排序;最后,将两个有序子数组合并回大数组,即得到有序数组。 举例:假设数组为[5,2,4,1,3],将数组划分为[5,2]和[4,1,3],使用插入排序,得到[2,5]和[1,3,4],将两个有序数组合并,即得到有序数组[1,2,3,4,5].
基数排序是一种非比较排序算法,其基本思想如下:将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
举例说明:
假设输入的数组为arr = [329, 457, 657, 839, 436, 720, 355]
首先将每个元素都统一为3位,即329变为329,457变为457,657变为657,839变为839,436变为436,720 变为720,355变为355;
从低位到高位开始排序,以个位数字为例,将数组中的元素按照个位数字排序,得到[329, 436, 657, 839, 720, 355, 457];
然后再以十位数字为例,将数组中的元素按照十位数字排序,得到[355, 329, 436, 457, 657, 720, 839];
最后,以百位数字为例,将数组中的元素按照百位数字排序,得到[329, 355, 436, 457, 657, 720, 839]。
经过上述三步排序,最终得到升序排序结果为[329, 355, 436, 457, 657, 720, 839]。
三.排序方法比较
冒泡排序是最简单的排序方法,但它的运行效率也是最慢的,它每次比较两个相邻元素,并且交换位置,因此比较和交换次数有可能非常多。
插入排序在部分有序数组中表现较为优秀,但对完全无序数组来说,性能依然很差。
选择排序比插入排序要好一些,它每次从剩余未排序元素中选出最小的,储存到已排序的末尾。
快速排序是最快的排序算法之一,它采用分治法思想,每次都选一个基准元素,把所有元素按照大小分成两个部分,然后对这两部分进行递归排序。
堆排序是一种基于二叉树的排序方法,它只需要进行一次排序,但每次都需要将数组转换为最大堆,这种时间复杂度也较高。
希尔排序是插入排序的一种变种,它通过设定一定的步长来进行排序,速度比插入排序快一些。
归并排序是分治法的一种实现,它将原始数组分成若干个子数组,然后再将子数组排序,最后将有序的子数组合并。
基数排序是一种特殊的桶排序,它将整数按照位数分配到不同的桶中,然后再对每个桶进行分别排序,最后将各个桶进行合并
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。