三种简单排序算法及实现
- 格式:pdf
- 大小:1.40 MB
- 文档页数:2
排序的几种方式在日常生活中,我们经常需要对事物进行排序,以便更好地组织和理解信息。
排序是一种将元素按照一定的规则进行排列的方法,可以应用于各种领域,如数字排序、字母排序、时间排序等。
本文将介绍几种常用的排序方式,包括冒泡排序、选择排序、插入排序、快速排序和归并排序。
一、冒泡排序冒泡排序是一种简单直观的排序方法,通过比较相邻元素的大小,将较大的元素逐渐“冒泡”到右侧,较小的元素逐渐“沉底”到左侧。
这个过程会不断重复,直到所有元素都按照升序排列。
冒泡排序的基本思想是从第一个元素开始,依次比较相邻的两个元素,如果前面的元素大于后面的元素,则交换它们的位置。
经过一轮比较后,最大的元素会“冒泡”到最右侧,然后再对剩下的元素进行相同的比较,直到所有元素都有序排列。
二、选择排序选择排序是一种简单直观的排序方法,它的基本思想是每次从待排序的元素中选择最小(或最大)的元素,放到已排序序列的末尾,直到所有元素都有序排列。
选择排序的过程可以分为两个部分:首先,在未排序的序列中找到最小(或最大)的元素,然后将其放到已排序序列的末尾;其次,将剩下的未排序序列中的最小(或最大)元素找到,并放到已排序序列的末尾。
这个过程会不断重复,直到所有元素都有序排列。
三、插入排序插入排序是一种简单直观的排序方法,它的基本思想是将待排序的元素逐个插入到已排序序列的适当位置,最终得到一个有序序列。
插入排序的过程可以分为两个部分:首先,将第一个元素看作已排序序列,将剩下的元素依次插入到已排序序列的适当位置;其次,重复上述过程,直到所有元素都有序排列。
插入排序的过程类似于整理扑克牌,将新抓到的牌插入到已有的牌中。
四、快速排序快速排序是一种常用的排序方法,它的基本思想是通过一趟排序将待排序序列分割成独立的两部分,其中一部分的所有元素都小于另一部分的所有元素。
然后对这两部分继续进行排序,直到整个序列有序。
快速排序的过程可以分为三个步骤:首先,从序列中选择一个基准元素;其次,将比基准元素小的元素放在左侧,比基准元素大的元素放在右侧;最后,递归地对左右两个部分进行排序。
数字的顺序排列方法数字的顺序排列在我们日常生活中非常常见。
无论是整数还是小数,数字的排列顺序对我们的计算和理解都至关重要。
在本文中,我们将探讨一些数字的顺序排列方法,包括升序排列和降序排列。
一、升序排列升序排列是指将一组数字按照从小到大的顺序进行排列。
这种排列方法可以帮助我们快速查找最小值或者整理数据。
下面是一些常见的升序排列方法:1. 选择排序法:选择排序法是一种简单直观的排序方法。
该方法的基本步骤是首先从待排序的数据中选择最小的元素,然后将其放在序列的起始位置;接着在剩余的未排序数据中选择最小的元素,放在已排序序列的末尾;以此类推,直到所有的数据都排列完成。
2. 冒泡排序法:冒泡排序法是一种比较相邻元素并交换的排序方法。
该方法的基本步骤是从第一个元素开始,比较该元素与其后面的元素,如果前者大于后者,则交换它们的位置;接着对第二个元素和之后的元素进行比较,以此类推,直到最后一个元素。
重复以上步骤,直到所有的数据都排列完成。
3. 插入排序法:插入排序法是一种逐个将元素插入已排序序列的排序方法。
该方法的基本步骤是首先将序列的第一个元素视为已排序序列,然后从第二个元素开始,逐个将元素插入已排好序的序列中的适当位置,直到所有的数据都排列完成。
二、降序排列降序排列是指将一组数字按照从大到小的顺序进行排列。
这种排列方法可以帮助我们查找最大值或者从大到小整理数据。
下面是一些常见的降序排列方法:1. 快速排序法:快速排序法是一种基于分治思想的排序方法。
该方法的基本步骤是首先选择一个基准元素,然后将其他元素与基准元素进行比较,将小于等于基准的元素放在基准元素的左边,大于基准的元素放在基准元素的右边;接着对左右两个子序列进行递归快速排序,直到所有的数据都排列完成。
2. 堆排序法:堆排序法是一种基于二叉堆的排序方法。
该方法的基本步骤是首先将待排序的序列构建成一个大顶堆或小顶堆,然后将堆顶元素与序列最后一个元素进行交换,并将堆的大小减1;接着重新调整剩余元素的堆结构,重复以上步骤,直到所有的数据都排列完成。
C语言中的算法实现算法是计算机科学中非常重要的概念,它是解决问题的一系列步骤或指令集。
在C语言中,我们可以使用不同的方法来实现算法。
本文将介绍一些常见的C语言算法实现方式。
一、排序算法1. 冒泡排序冒泡排序是一种简单但效率较低的排序算法。
它通过不断比较相邻的元素,并按照规则交换它们的位置,直到整个序列排序完成。
2. 选择排序选择排序是一种简单而直观的排序算法。
它每次从未排序的序列中选择最小(或最大)的元素,并将其放置在已排序序列的末尾。
3. 插入排序插入排序是一种简单且高效的排序算法。
它通过构建有序序列,对未排序的元素逐个插入到已排序的序列中,直到所有元素都被插入完成。
二、查找算法1. 顺序查找顺序查找是一种简单的查找算法。
它从列表的开头开始逐个比较元素,直到找到目标元素或查找完整个列表。
2. 二分查找二分查找是一种高效的查找算法,但要求列表必须是有序的。
它通过将待查找区域分成两部分,判断目标元素落在哪一部分,从而缩小查找范围,直到找到目标元素或确定不存在。
三、递归算法递归是一种常用的算法设计技巧。
它通过在函数内调用自身来解决相同问题的不同实例。
在C语言中,递归函数需要定义出口条件,以避免无限递归。
四、动态规划算法动态规划是一种用于解决具有重叠子问题和最优子结构性质的问题的方法。
它将问题分解为一系列子问题,并以自底向上的方式求解子问题,最终得到整体问题的解。
在C语言中,可以使用循环、数组和指针等特性来实现动态规划算法,从而有效地解决问题。
五、图算法图是一种用于描述对象之间关系的数据结构,图算法是解决图相关问题的一类算法。
常见的图算法包括深度优先搜索(DFS)和广度优先搜索(BFS)。
六、字符串算法字符串算法用于处理字符串相关的问题,如字符串匹配、编辑距离等。
C语言提供了一系列字符串处理函数,如strlen、strcpy等,可以方便地实现字符串算法。
七、数学算法C语言在数学算法方面提供了丰富的库函数支持,如求平方根、对数、指数等。
最简单的排序排序是一种常见的操作,可以将一组元素按照一定的规则重新排列,使其达到某种有序的状态。
排序在生活中随处可见,比如我们买菜时,需要将菜按照大小、种类进行整理;在图书馆,图书也是按照编号或者分类进行排序的。
下面我们来介绍几种最简单的排序算法。
1. 冒泡排序冒泡排序是一种简单直观的排序算法,它重复地遍历要排序的元素,比较相邻的两个元素,如果它们的顺序错误就交换位置,直到没有需要交换的元素为止。
这样最大(或最小)的元素就会像气泡一样逐渐升(或降)到最后的位置。
2. 选择排序选择排序是一种简单直观的排序算法,它的工作原理如下:首先在未排序序列中找到最小(或最大)元素,存放到排序序列的起始位置,然后再从剩余未排序元素中继续寻找最小(或最大)元素,放到已排序序列的末尾。
以此类推,直到所有元素均排序完毕。
3. 插入排序插入排序是一种简单直观的排序算法,它的工作原理如下:将数组分成已排序部分和未排序部分,初始时已排序部分只有一个元素,然后将未排序部分的元素逐个插入到已排序部分的合适位置,直到所有元素都被插入到已排序部分为止。
4. 快速排序快速排序是一种高效的排序算法,它的工作原理如下:选择一个基准元素,将大于基准元素的元素放到右边,小于基准元素的元素放到左边,然后再对左右两个子序列分别进行快速排序,直到整个序列有序。
以上是几种最简单的排序算法,它们都有各自的特点和适用场景。
在实际应用中,我们可以根据问题的具体需求选择合适的排序算法。
排序算法的效率也是我们需要考虑的一个重要因素,通常来说,快速排序是效率最高的排序算法之一。
排序是一种常见的操作,可以帮助我们将一组元素按照一定的规则重新排列,使其达到某种有序的状态。
冒泡排序、选择排序、插入排序和快速排序是几种最简单的排序算法,它们都有各自的特点和适用场景。
在实际应用中,我们可以根据问题的具体需求选择合适的排序算法,以提高效率和准确性。
通过学习和掌握这些排序算法,我们可以更好地理解和应用排序的原理和方法。
SIMPLE算法及计算例子算法是指一系列解决问题的步骤和规则,是计算机科学的基础。
简单算法是指易于理解和实现的算法,适用于一些简单的问题。
下面是几个简单算法及其计算例子。
1.冒泡排序算法:冒泡排序是一种基础的排序算法,它依次比较相邻的元素,如果顺序不对则进行交换,直到整个序列有序为止。
计算例子:假设有一个数字序列[5,3,8,4,2],使用冒泡排序算法将其从小到大进行排序。
-第一次迭代:比较5和3,交换位置,得到序列[3,5,8,4,2]-第二次迭代:比较5和8,位置不变,继续比较下一对数字-第三次迭代:比较8和4,交换位置,得到序列[3,5,4,8,2]-第四次迭代:比较8和2,交换位置,得到序列[3,5,4,2,8]经过第四次迭代后,发现序列已经是有序的,算法结束。
最终的有序序列为[2,3,4,5,8]。
2.欧几里得算法:欧几里得算法用于计算两个非负整数的最大公约数。
算法基于两个数的辗转相除法,即先用较大数除以较小数得到余数,然后用较小数除以余数,依次循环,直到余数为0为止。
计算例子:假设需要计算36和48的最大公约数。
-第一次迭代:48除以36,余数为12-第二次迭代:36除以12,余数为0迭代过程中余数为0时,算法结束,最大公约数为123.线性算法:线性算法用于在一个无序列表或数组中寻找一些元素的位置。
它是一种直观的方法,逐个比较列表中的元素,当找到匹配的元素时返回其位置,否则返回未找到。
计算例子:假设有一个列表[4,2,7,1,9,5],需要找到数字7的位置。
-从列表的第一个元素开始,比较其与目标数字7-第一次比较:4!=7,继续比较下一个元素-第二次比较:2!=7,继续比较下一个元素-第三次比较:7=7,找到匹配,返回位置3最终结果为数字7的位置为3这些是一些简单算法及其计算例子,它们是计算机科学中最基础的算法之一、无论是冒泡排序还是求最大公约数,这些算法都体现了计算机程序处理问题的思维方式和逻辑。
三个数怎么比较排序的方法三个数的比较排序方法有许多,下面我会详细介绍其中一些常用的方法,包括冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序。
1. 冒泡排序:冒泡排序是最简单的排序算法之一。
它通过多次比较并交换相邻的两个元素来进行排序。
具体步骤如下:- 从第一个数开始,依次与后面的数进行比较,如果当前数比后面的数大,则交换它们的位置。
- 每完成一次遍历,最大的数就会“冒泡”到最后的位置。
- 重复上述步骤,但是每次比较的范围减一,直到所有数都被排序。
2. 选择排序:选择排序思路简单,每次通过找出最小的数,并将其与未排序部分的第一个数交换位置来进行排序。
具体步骤如下:- 遍历未排序部分,找到最小的数,并记录其下标。
- 将最小的数与未排序部分的第一个数交换位置。
- 重复上述步骤,但是每次比较的范围减一,直到所有数都被排序。
3. 插入排序:插入排序将待排序的数插入到已排序部分的合适位置。
具体步骤如下:- 从第二个数开始,与前面的已排序部分进行比较,找到合适的位置。
- 如果当前数比前面的数小,则将前面的数后移一位,直到找到合适的位置。
- 将当前数插入到找到的位置。
- 重复上述步骤,直到所有数都被排序。
4. 快速排序:快速排序是一种高效的排序算法。
它通过把数组分成两部分,并对这两部分分别进行排序来实现排序的目的。
具体步骤如下:- 选择一个基准数,可以是数组中的任意一个数。
- 将数组分成小于基准数的部分和大于基准数的部分。
- 递归地对两部分分别进行排序。
- 合并两部分,得到最终排序结果。
5. 归并排序:归并排序是一种稳定的排序算法,它使用分治的思想,将数组分成多个子数组,然后合并这些子数组以获得排序结果。
具体步骤如下:- 将数组分成两个部分,分别对这两个部分进行排序。
- 合并两个排序好的部分,得到一个排序好的数组。
- 对合并后的数组重复上述步骤,直到所有子数组都被合并。
6. 堆排序:堆排序是一种基于完全二叉堆的排序算法。
【转】三种快速排序算法以及快速排序的优化⼀. 快速排序的基本思想快速排序使⽤分治的思想,通过⼀趟排序将待排序列分割成两部分,其中⼀部分记录的关键字均⽐另⼀部分记录的关键字⼩。
之后分别对这两部分记录继续进⾏排序,以达到整个序列有序的⽬的。
⼆. 快速排序的三个步骤1) 选择基准:在待排序列中,按照某种⽅式挑出⼀个元素,作为 “基准”(pivot);2) 分割操作:以该基准在序列中的实际位置,把序列分成两个⼦序列。
此时,在基准左边的元素都⽐该基准⼩,在基准右边的元素都⽐基准⼤;3) 递归地对两个序列进⾏快速排序,直到序列为空或者只有⼀个元素;三. 选择基准元的⽅式对于分治算法,当每次划分时,算法若都能分成两个等长的⼦序列时,那么分治算法效率会达到最⼤。
也就是说,基准的选择是很重要的。
选择基准的⽅式决定了两个分割后两个⼦序列的长度,进⽽对整个算法的效率产⽣决定性影响。
最理想的⽅法是,选择的基准恰好能把待排序序列分成两个等长的⼦序列。
⽅法⼀:固定基准元(基本的快速排序)思想:取序列的第⼀个或最后⼀个元素作为基准元。
/// <summary>/// 1.0 固定基准元(基本的快速排序)/// </summary>public static void QsortCommon(int[] arr, int low, int high){if (low >= high) return; //递归出⼝int partition = Partition(arr, low, high); //将 >= x 的元素交换到右边区域,将 <= x 的元素交换到左边区域QsortCommon(arr, low, partition - 1);QsortCommon(arr, partition + 1, high);}/// <summary>/// 固定基准元,默认数组第⼀个数为基准元,左右分组,返回基准元的下标/// </summary>public static int Partition(int[] arr, int low, int high){int first = low;int last = high;int key = arr[low]; //取第⼀个元素作为基准元while (first < last){while (first < last && arr[last] >= key)last--;arr[first] = arr[last];while (first < last && arr[first] <= key)first++;arr[last] = arr[first];}arr[first] = key; //基准元居中return first;}注意:基本的快速排序选取第⼀个或最后⼀个元素作为基准。
简单排序算法排序算法是计算机科学中最基本、最常用的算法之一。
通过对原始数据集合进行排序,可以更方便地进行搜索、统计、查找等操作。
常用的排序算法有冒泡排序、选择排序、插入排序等。
本文将介绍这些简单排序算法的具体实现及其优缺点。
一、冒泡排序(Bubble Sort)冒泡排序是一种基础的交换排序算法。
它通过不断地交换相邻的元素,从而将数据集合逐渐排序。
具体实现步骤如下:1.比较相邻的元素。
如果第一个比第二个大,就交换它们两个;2.对每一对相邻元素做同样的工作,从第一对到最后一对,这样一轮排序后,就可以确保最后一个元素是最大的元素;3.针对所有元素重复以上的步骤,除了最后一个;4.重复步骤1~3,直到排序完成。
冒泡排序的优点是实现简单、容易理解。
缺点是排序效率较低,尤其是对于较大的数据集合,时间复杂度为O(n²)。
二、选择排序(Selection Sort)选择排序是一种基础的选择排序算法。
它通过在数据集合中选择最小的元素,并将其放置到最前面的位置,然后再从剩余元素中选出最小的元素,放置到已排序部分的末尾。
具体实现步骤如下:1.在未排序序列中找到最小元素,存放到排序序列的起始位置;2.再从剩余未排序元素中继续寻找最小元素,放到排序序列末尾;3.重复步骤1~2,直到排序完成。
选择排序的优点是实现简单、固定时间复杂度O(n²)。
缺点是排序效率仍然较低,尤其是对于大数据集合,因为每次只能交换一个元素,所以相对于冒泡排序,它的移动次数固定。
三、插入排序(Insertion Sort)插入排序是一种基础的插入排序算法。
它将未排序的元素一个一个插入到已排序部分的正确位置。
具体实现步骤如下:1.从第一个元素开始,该元素可以认为已经被排序;2.取出下一个元素,在已经排序的元素序列中从后往前扫描;3.如果该元素(已排序)大于新元素,将该元素移到下一位置;4.重复步骤3,直到找到已排序的元素小于或等于新元素的位置;5.将新元素插入到该位置后;6.重复步骤2~5,直到排序完成。
排序的五种方法一、冒泡排序。
冒泡排序就像水里的泡泡一样,大的泡泡慢慢往上冒。
它的原理是比较相邻的元素,如果顺序不对就交换位置。
比如说有一堆数字,就从第一个数字开始,和它后面的数字比,如果前面的比后面的大,就把它们换过来。
这样一轮一轮地比较,每一轮都会把最大的数字像泡泡一样“冒”到最后面。
这个方法很简单,但是如果数据很多的话,就会比较慢啦。
就像一个小蜗牛,虽然能到达终点,但是速度有点慢哟。
二、选择排序。
选择排序呢,就像是在一群小伙伴里选最高的那个。
它先在未排序的序列里找到最小(或者最大)的元素,然后把这个元素放到已排序序列的末尾。
就好比在一群小朋友里,先找出最矮的那个小朋友,让他站在最前面,然后再在剩下的小朋友里找最矮的,依次类推。
这个方法比冒泡排序在某些情况下会快一点,不过它也有自己的小脾气,不是在所有数据情况下都超级高效的呢。
三、插入排序。
插入排序就像是我们平时整理扑克牌一样。
假设我们手里已经有一部分排好序的牌,然后拿到一张新牌,就把这张新牌插入到合适的位置。
对于一组数字也是这样,从第二个数字开始,把它插入到前面已经排好序的数字里合适的地方。
如果这个数字比前面的大,就往后放,如果比前面的小,就往前找合适的位置插进去。
这个方法在数据比较有序的情况下,速度还是挺快的,就像一个聪明的小助手,能很快地把东西整理好。
四、快速排序。
快速排序就像是一个很厉害的魔法师。
它先选一个基准值,然后把数组里的数字分成两部分,一部分比基准值小,一部分比基准值大。
然后再对这两部分分别进行同样的操作,就像把一个大问题分成很多小问题,然后各个击破。
这个方法在大多数情况下速度都非常快,就像一阵旋风,能迅速把数据排好序。
不过它也有点小复杂,就像魔法师的魔法一样,不是那么容易一下子就完全理解的呢。
五、归并排序。
归并排序就像是两个队伍在合并。
它把数组分成两部分,然后分别对这两部分进行排序,排好序之后再把这两部分合并起来。
这个过程就像是两个已经排好队的小队伍,要合并成一个大队伍,在合并的时候还要保证顺序正确。
2019年1月前农业技术高速发展背景下,应该借助基因编辑技术将植物育种工作完善,以此实现植物育种的科学提升,满足植物育种工作实际需求。
通过本文的研究和分析,将植物育种基因编辑技术的形式及应用领域归纳为以下几点:①改良农作物品质;②在基因工程育种中的应用;③植物基因功能研究。
只有保障了以上三点基因编辑技术的应用,才能提升植物育种水平。
参考文献[1]姚祝平,程远,万红建,等.CRISPR/Cas9基因编辑技术在植物基因工程育种中的应用[J].分子植物育种,2017,11(7):2647~2655.[2]许丽,李祯祺,等.基因组编辑育种技术及国内外发展态势分析[J].生物产业技术,2016,22(4):46~51.[3]郑红艳,王磊.CRISPR/Cas基因编辑技术及其在作物育种中的应用[J].生物技术进展,2018,22(3):120~125.[4]王艳芳,苏婉玉,曹绍玉,等.新型基因编辑技术发展及在植物育种中的应用[J].西北农业学报,2018,27(5):617~625.[5]段莹星.CRISPR/Cas9基因编辑技术应用现状[J].山西农经,2018,25 (10):111~114.收稿日期:2018-12-15三种简单排序算法及实现王韬睿(山东省烟台经济技术开发区高级中学,山东省烟台市264006)【摘要】本文首先简要介绍了数据结构和算法的概念,以及二者之间的关系。
然后重点介绍了三种简单的排序算法:选择排序、插入排序、冒泡排序,说明了它们的实现过程并给出程序代码,同时横向比较他们的优缺点,说明了每种算法的实际使用情况,最后得出熟练运用排序算法可以解决许多现实生活中问题的结论。
【关键词】冒泡排序;快速排序;插入排序;算法实际应用【中图分类号】TP301.6【文献标识码】A【文章编号】1006-4222(2019)01-0284-021数据结构与算法1.1数据结构数据结构是计算机存储、组织数据的方式,旨在便于计算机的访问和修改。
数据结构包括逻辑数据结构和物理数据结构,常见的逻辑数据结构有集合、树形结构、线性结构和图形结构;物理结构就是数据在磁盘中存储的方式,最简单的是顺序存储,当所需存储的数据太大,现有的磁盘空间没有一整块空间去存储时,就使用链式方法来存储,比如指针的使用。
数据结构是算法的基础,选用适合的数据结构实现算法能事半功倍,比如对于排序使用数组(Array)是更优的选择、对于最短路径算法使用队列(Queue)更为合适。
较底层的数据结构是为算法服务的,而算法也是围绕数据结构展开的。
1.2算法算法(Algorithm)是指针对某一问题解决方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着一种用系统的方法解决问题的策略机制。
从宏观意义上来说,我们日常生活中解决问题的方法都可以称作算法,比如我们日常生活中经常接触到的分治法、动态规划法,下文所提到的快速排序即是分治法的应用。
而一个实用可靠的算法应该包括五个特点:①有穷性:算法必须能在一定的步骤后结束;②确切性:算法的每条语句都应有确切的定义;③输入项:一个算法会有输入以表示运算对象的初始情况;④输出项:一个算法有一个或多个输出,以反映对输入数据处理后的结果[1];⑤可行性:算法原则上能精确的运行。
其中部分算法可以没有输入项,但所有算法都需要有输出项。
算法的好坏通常用时间复杂度和空间复杂度来衡量。
时间复杂度从表面上理解就是一个算法所耗费的时间,所需的时间越短,算法越优;而空间复杂度是指算法在计算机内执行时所需存储空间的度量,一般来说一个好的算法这两项复杂度都不会太高。
互联网时代算法早已经进入了我们的生活,我们都在使用的搜索引擎所运用的匹配和排名算法、网购所使用的电子商务平台对大数据和云计算的使用,这些统统都是算法的应用。
作为一种较基础的算法,排序算法在日常生活中出现的频率很高,排队按到达时间先后排序,在数据库中的信息按姓名拼音首字母排序,考试成绩按总分排序等等。
一个有趣有意义的算法通常都是为解决实际问题而创造的。
2常见的排序算法及实现排序算法大体分为两种:比较算法和非比较算法。
非比较算法适用情形较少且使用频率低,比如桶排序,在此不予说明。
比较排序算法是现在使用最多的算法,基本上常用的排序算法都是通过两数的比较来实现排序目的的,比如下文提到的冒泡排序、快速排序和插入排序:2.1冒泡排序冒泡排序是一个基础而又简单的排序算法。
它的实现过程是通过比较数组中相邻的元素并在必要的情况下进行交换。
以升序为例,定义排序数组q[n],如果第一个元素q[0]比第二个元素q[1]大,就交换他们两个;从开始第一对数据到结尾最后一对,对每一对相邻元素做同样的工作,在第一次循环结束后,数组最后的元素n应该会是数组中最大的数;然后针对前n-1的元素重复以上的步骤,每次把一个元素归位;第i次循环对前n-i+1个元素重复上面的步骤,直到没有任何一对数字需要比较。
这个归位过程就像水中升起的气泡一样,因此得名冒泡排序。
通过代码实现我们很容易就知道即使在最优的情况下,冒泡排序的时间复杂度也是O(n2),而算法的核心部分是双重嵌套循环,很多人都曾尝试过对它进行改进,最为著名的鸡尾酒算法,即定向冒泡排序。
图1是定向冒泡排序算法的一种C++实现。
2.2快速排序快速排序由C.A.R.Hoare在1960年发明[2],很快成为最常用的排序算法,并被选为20世纪十大算法。
相比冒泡排序,快速排序的每次交换是跳跃式的,是二分法的应用。
当我们从小论述2842019年1月图1定向冒泡排序实现代码到大排序时,每次排序时取区间中的一个数作为基准值,将小于基准点的数全部放到基准点的左边,将大于等于基准点的数放到基准点的右边。
这样在每次交换时就不会像冒泡排序一样只能在相邻的数之间进行交换,交换的距离就大的多了,因此总的比较和交换次数就少了,速度自然就快了[3]。
图2是快速排序的一种C++实现。
当然在最坏的情况下,即要进行所有数据的交换时,它的时间复杂度也是O (n 2)。
虽然最坏情况时间复杂度很差,但是快速排序通常是实际排序应用中最好的选择,因为他的平均性能非常好:它的期望时间复杂度为O (nlogN ),而且O (nlogN )中隐含的常数因子非常小[3]。
2.3插入排序另一种常用的简单排序是插入排序,其核心思想就是查询加上插入。
为了便于理解我们将数组分为两部分:已排序好的和未经排序的。
将未排序的元素插入到已排序好的序列中,直到数组整体都具有有序性。
定义排序数组q[n],首先我们假设数组中的第一个元素q[0]是有序的,定义当前要插入的元素为k ,要插入的元素的值为temp ,循环将temp 与已排序好的元素比较,当这个元素大于temp 时该元素向后移动,最后当存在大于temp 的数时将temp 插入空位,将这个过程重复n-1次即可完成排序。
图3是一种直接插入排序的C++实现。
这种直接进行循环比较后插入的解决方案不是最优的,可以用二分法来优化,在寻找插入temp 插入的位置时,直接将temp 的值与q[(i-1)/2]的值比较,如果temp 的关键码值小于q[i-1/2]的关键码值,则说明temp 只能插入q[0]到q[i-1/2]之间,反之将temp 插入到q[i-1/2]~q[i]之间。
经过一次比较就可以排除一半,大大减少了比较次数,加速了排序速度。
插入排序的平均时间复杂度是O (n 2),但在最优时只需进行n-1次比较即可,而最坏的情况是序列是降序排列,那么此时需要进行的比较共有n (n-1)/2次。
3横向对比以上算法的优劣(1)冒泡排序作为基础排序,它是最经典的排序算法。
本身不复杂的原理加上不难的代码实现让它成为初学者的排序入门必学排序算法。
但它也有不足的地方,双重循环使得它的时间复杂度很高,为O (n 2),所以当实际情况数据量较大时,冒泡排序就没有很大的实用价值[4]。
(2)快速排序是现今应用最广的排序算法。
二分法加上递归的思想的应用,容易理解。
平均时间复杂度为O (nlogn ),是文中三种简单排序算法中最快的一个。
但它是不稳定的,而且数据规模大时时间复杂度会上浮至O (n 2),这给它的使用带来限制。
(3)简单插入排序在最好情况下,需要比较n-1次,无需交换元素,时间复杂度为O (n );在最坏情况下,时间复杂度为O (n 2)。
但是在数组元素随机排列的情况下,插入排序还是要优于上面两种排序的。
虽然相比前两个算法更不容易理解,但是许多更加复杂的衍生排序算法都是基于插入排序进行改进而得到的。
对不同数据规模和数据格式表现不同也是这些比较算法的共同特点。
这就产生了这些算法运用时的局限性,所以对特定的情境选择适合的算法是必要的。
4应用场景日常生活中很多看似常理的事情都是排序算法的应用。
在计算机方面,许多数据管理系统中,每条信息都是按一定的关键字排序的;C++标准库中的sort 排序函数使用的就是类似快速排序的排序方法。
在生活中方面,打扑克牌游戏在摸牌时向手牌中插入新摸到的牌时的策略就是插入排序的体现。
所以熟练运用排序算法,将理论和现实融合,可以解决许多生活中的问题。
参考文献[1]KurtMehlhorn ,PeterSanders.算法与数据结构[M].清华大学出版社,2013.[2]霍红卫,许进.快速排序算法研究[J].微电子学与计算机,2002,19(6):6~9.[3]啊哈磊.啊哈!算法[M].人民邮电出版社,2014.[4]科曼.算法导论(原书第3版)[M].机械工业出版社,2012.收稿日期:2018-12-16图2快速排序实现代码图3插入排序实现代码论述285。