排序
选择排序
选择排序开始的时候,我们扫描整个列表,找到它的最小元素,然后和第一个元素交换,将最小元素放到它在有序表中的最终位置上。然后我们从第二个元素开始扫描列表,找到最后n-1个元素中的最小元素,再和第二个元素交换位置,把第二小的元素放在它的最终位置上。
不稳定的!
时 间 复 杂 度 : n 2 , 交 换 次 数 : n 时间复杂度:n^2,交换次数:n 时间复杂度:n2,交换次数:n
冒泡排序
蛮力法在排序问题上还有另一个应用,它比较表中的相邻元素,如果它们是逆序的话就交换它们的位置。重复多次以后,最终,最大的元素就“沉到”列表的最后一个位置。第二遍操作将第二大的元素沉下去。
时 间 复 杂 度 : n 2 , 交 换 次 数 : n 2 时间复杂度:n^2,交换次数:n^2 时间复杂度:n2,交换次数:n2
插入排序
一般来说,我们可以从右到左扫描这个有序的子数组,直到遇到第一个小于等于Am-1]的元素,然后把A[mー1]插在该元素的后面。这种算法被称为直接插入排序( straight insertion sort),或者简称为插入排序(insertion sort)。
图4.4是该算法的操作图示。
89|45 68 90 29 34 17
45 89|68 90 29 34 17
图4.4用插入排序法进行排序的例子。一条竖线把输入的有序部分和剩下的元素分开正在插入的元素用粗体字表示
时 间 复 杂 度 : n 2 , 交 换 次 数 : n 时间复杂度:n^2,交换次数:n 时间复杂度:n2,交换次数:n
归并排序
合并排序是成功应用分治技术的一个完美例子。对于一个需要排序的数组A[0.n-1]合并排序把它一分为二:A[0…(n/2)-1]和A[(n/2)…n-1],并对每个子数组递归排序,然后把这两个排好序的子数组合并为一个有序数组。
时 间 复 杂 度 : n l o g n 时间复杂度:nlogn 时间复杂度:nlogn
快速排序
快速排序是另一种基于分治技术的重要排序算法。不像合并排序是按照元素在数组中的位置对它们进行划分,快速排序按照元素的值对它们进行划分。我们在4.5节中讨论选择问题时介绍过数组划分的思想了。划分是对给定数组中的元素的重新排列,使得A[s]左边的元素都小于等于A[s],而所有A[s]右边的元素都大于等于A[s].
显然,建立了一个划分以后,A[j]已经位于它在有序数组中的最终位置,接下来我们可以继续对A[s]前和A[S]后的子数组分别进行排序(例如,使用同样的方法)。注意,它与合并排序的不同之处在于:在合并排序算法中,将问题划分成两个子问题是很快的,算法的主要工作在于合并子问题的解:而在快速排序中,算法的主要工作在于划分阶段,而不需要再去合并子问题的解了。
有序退化成冒泡排序。
时 间 复 杂 度 : n l o g n , 最 差 n 2 时间复杂度:nlogn,最差n^2 时间复杂度:nlogn,最差n