排序算法gydF4y2Ba
一个gydF4y2Ba排序算法gydF4y2Ba算法是由一系列指令组成的吗gydF4y2Ba数组gydF4y2Ba作为输入,对数组(有时称为列表)执行指定的操作,并输出一个排序的数组。排序算法通常在计算机科学课程的早期教授,因为它们提供了一种直接的方式来介绍其他关键的计算机科学主题,如gydF4y2Ba大0符号gydF4y2Ba,gydF4y2Ba分治法gydF4y2Ba方法和数据结构,例如gydF4y2Ba二叉树gydF4y2Ba,gydF4y2Ba堆gydF4y2Ba.有很多因素需要考虑gydF4y2Ba选择排序算法gydF4y2Ba使用。gydF4y2Ba
内容gydF4y2Ba
排序算法gydF4y2Ba
换句话说,一个排序的数组是一个特定顺序的数组。例如,gydF4y2Ba 按字母顺序排序,gydF4y2Ba 一个整数列表是否按递增顺序排序,和gydF4y2Ba 是按递减顺序排序的整数列表。gydF4y2Ba
一个排序算法以一个数组作为输入和输出gydF4y2Ba排列gydF4y2Ba对数组进行排序。gydF4y2Ba
排序算法有两大类:gydF4y2Ba整数类型gydF4y2Ba而且gydF4y2Ba比较各种gydF4y2Ba.gydF4y2Ba
比较各种gydF4y2Ba
比较排序在算法的每一步比较元素,以确定一个元素应该在另一个元素的左边还是右边。gydF4y2Ba
比较排序的实现通常比整数排序更简单,但是比较排序的下界为gydF4y2Ba ,这意味着,平均而言,比较排序不能比gydF4y2Ba .算法的下界是gydF4y2Ba最坏的gydF4y2Ba的运行时间gydF4y2Ba最好的gydF4y2Ba给定问题的可能算法。这里的“平均”部分很重要:如果输入的列表是,有许多算法在非常快的时间内运行gydF4y2Ba已经gydF4y2Ba排序,或者有一些非常特殊(总体上不太可能)的性质。列表只有一种排列方式是有序的,但是gydF4y2Ba 可能的列表,所以输入已经排好序的可能性很小,平均来说,列表不会排得很好。gydF4y2Ba
基于比较的排序算法的运行时间是有限的gydF4y2Ba .gydF4y2Ba
比较排序可以建模为大型排序gydF4y2Ba二叉树gydF4y2Ba称为决策树,其中每个节点代表一个比较。因为排序后的列表是输入列表的某种排列,对于一个长度为一定的输入列表gydF4y2Ba ,有gydF4y2Ba 可能的排列。这是一个决策树,因为每一个gydF4y2Ba 由一个叶表示,算法到达每个叶的路径是产生特定顺序的一系列比较和结果。gydF4y2Ba
在树的每一层都进行比较。比较发生了,我们沿着树向下移动;直到算法到达树的叶子,每个排列都会有一个叶子,所以有gydF4y2Ba 叶子。gydF4y2Ba
每次比较都会使算法未来必须进行的比较次数减少一半(因为如果算法在给定步骤中选择了节点的右边缘,它将不会搜索连接到左边缘的节点和路径)。因此,算法执行gydF4y2Ba 比较。任意二叉树gydF4y2Ba ,具有小于或等于的叶数gydF4y2Ba .gydF4y2Ba
从这个,gydF4y2Ba 以gydF4y2Ba对数gydF4y2Ba结果gydF4y2Ba 从gydF4y2Ba斯特林近似gydF4y2Ba,gydF4y2Ba 因此,gydF4y2Ba
整数类型gydF4y2Ba
整数排序有时被称为计数排序(尽管有一种特定的整数排序算法称为计数排序)。整数排序不进行比较,因此它们不受gydF4y2Ba .为每个元素确定整数排序gydF4y2Ba 有多少元素小于gydF4y2Ba .如果有gydF4y2Ba 小于的元素gydF4y2Ba ,然后gydF4y2Ba 会放在哪里gydF4y2Ba 槽。该信息用于立即将每个元素放入正确的槽中—不需要重新排列列表。gydF4y2Ba
排序算法的性质gydF4y2Ba
所有排序算法都有一个共同的目标,那就是输出一个排序后的列表,但是每个算法执行这个任务的方式可能不同。在使用任何一种算法时,重要的是要知道它运行的速度和它在多大的空间中运行——换句话说,就是它的gydF4y2Ba时间复杂度gydF4y2Ba而且gydF4y2Ba空间复杂度gydF4y2Ba.如上一节所示,基于比较的排序算法的时间复杂度为gydF4y2Ba ,这意味着算法不能比gydF4y2Ba .然而,通常情况下,算法的运行时间是用大O来讨论的,而不是Omega。例如,如果一个算法的最坏情况运行时间为gydF4y2Ba ,则保证算法永远不会比gydF4y2Ba ,如果算法的平均情况运行时间为gydF4y2Ba ,那么平均来说,它不会比gydF4y2Ba .gydF4y2Ba
运行时间描述了一个算法在完成之前必须执行多少操作。空间复杂度描述了运行特定算法必须分配多少空间。例如,如果一个算法接收一个大小列表gydF4y2Ba ,并出于某种原因制作了一个新的大小列表gydF4y2Ba 对于中的每个元素gydF4y2Ba 时,算法需要gydF4y2Ba 空间。gydF4y2Ba
此外,对于排序算法,了解排序算法是否稳定有时是有用的。gydF4y2Ba
稳定gydF4y2Ba
如果一个排序算法保持了具有相等键值的元素的原始顺序(其中键值是算法排序的值),那么它就是稳定的。例如,gydF4y2Ba
当纸牌按值进行稳定排序时,两个5在排序输出中必须保持与它们原来的相同顺序。当它们用非稳定排序时,5s在排序输出中可能以相反的顺序结束。gydF4y2Ba
常用排序算法gydF4y2Ba
有许多不同的排序算法,有各种各样的优点和缺点。下面是一些常见的排序算法的例子。gydF4y2Ba
归并排序是一种基于比较的算法,主要关注如何将两个预先排序的数组合并在一起,从而使生成的数组也得到排序。gydF4y2Ba
插入排序是一种基于比较的算法,每次构建一个最终排序的数组。它遍历输入数组,每次迭代删除一个元素,找到元素在数组中的位置,然后将其放置在那里。gydF4y2Ba
冒泡排序是一种基于比较的算法,它比较数组中的每对元素,并在它们无序时交换它们,直到整个数组排序完毕。对于列表中的每个元素,算法比较每对元素。gydF4y2Ba
快速排序是一种基于比较的算法,它使用分治法对数组进行排序。算法选择一个主元,gydF4y2Ba ,然后将数组重新排列为两个子数组gydF4y2Ba ,使得所有元素都小于gydF4y2Ba ,gydF4y2Ba ,使得所有元素都大于或等于gydF4y2Ba .gydF4y2Ba
堆排序是一种基于比较的算法,它使用二进制堆数据结构对元素进行排序。它将输入分为已排序区域和未排序区域,并通过提取最大的元素并将其移动到已排序区域来迭代地缩小未排序区域。gydF4y2Ba
计数排序是一种整数排序算法,它假设每一个gydF4y2Ba 列表中的输入元素的键值为gydF4y2Ba 来gydF4y2Ba ,对于某个整数gydF4y2Ba .对于列表中的每个元素,计数排序确定小于它的元素的数量。计数排序可以使用此信息将元素直接放入输出数组的正确槽中。gydF4y2Ba
选择排序算法gydF4y2Ba
要为特定问题选择排序算法,请考虑运行时间、空间复杂度和输入列表的预期格式。gydF4y2Ba
算法gydF4y2Ba | 最好的gydF4y2Ba | 最坏的gydF4y2Ba | 平均情况gydF4y2Ba | 空间复杂度gydF4y2Ba | 稳定吗?gydF4y2Ba |
归并排序gydF4y2Ba | 是的gydF4y2Ba | ||||
插入排序gydF4y2Ba | 是的gydF4y2Ba | ||||
冒泡排序gydF4y2Ba | 是的gydF4y2Ba | ||||
快速排序gydF4y2Ba | 最好的gydF4y2Ba avggydF4y2Ba | 通常不是*gydF4y2Ba | |||
堆排序gydF4y2Ba | 没有gydF4y2Ba | ||||
计数排序gydF4y2Ba | 是的gydF4y2Ba |
*大多数快速排序实现都不稳定,尽管稳定的实现确实存在。gydF4y2Ba
在选择要使用的排序算法时,要权衡这些因素。例如,快速排序是一种非常快速的算法,但实现起来可能相当棘手;冒泡排序是一种缓慢的算法,但很容易实现。对于小数据集的排序,冒泡排序可能是一个更好的选择,因为它可以快速实现,但对于较大的数据集,快速排序带来的加速可能值得实现算法的麻烦。gydF4y2Ba
另请参阅gydF4y2Ba
参考文献gydF4y2Ba
- , d ., &, w .;gydF4y2Ba排序稳定性扑克牌gydF4y2Ba.检索自2016年5月18日gydF4y2Bahttps://en.wikipedia.org/wiki/File:Sorting_stability_playing_cards.svggydF4y2Ba