排序算法衍生问题学习笔记

1. 稳定性的定义和意义

排序算法的稳定性指,在排序过程中,如果待排序元素的值相等,那么这些元素在排序后的相对位置是否发生变化。如果排序前和排序后,元素的相对位置没有发生变化,则称该排序算法是稳定的。稳定性是排序算法一个很重要的性质,因为它在某些应用场景中至关重要。

例如,在考试时,成绩相同的学生名次是需要按照原有顺序进行排列的,否则会出现不公平的情况。在实际开发中,如果需要对多个数据项进行排序,如果某些数据项存在相同的值,而且排序算法不是稳定的,那么可能会导致出现错误的结果。因此,在很多场景下,我们都需要使用稳定的排序算法。

2. 快速排序的优化

快速排序是一种非常高效的排序算法,但是在某些情况下,它会变得非常慢,需要进行一些优化。以下是几种优化方式:

2.1 三数取中法

快排的时间复杂度与初始序列的有序度有关系。如果序列已经有序或者逆序,那么快排的效率会非常低。因此,对于一个乱序的序列,为了提高快排的效率,我们需要选取合适的主元,这样就可以将序列分割成两个长度相等的子序列。

三数取中法就是一种比较常用的方法。它选择序列的开始、中间和结尾位置上的三个元素,将它们排序,并取中间值作为主元。这样选出来的主元,能够更好地分割序列,避免了快排运行时间过长的问题。

2.2 随机化

快排的时间复杂度与初始序列的有序度有关系,如果序列越乱,快排的效率就越高。那么如何使得序列更加乱呢?有一种有效的方法就是随机化。

快排的分别是根据主元对序列进行分割,这个主元的选取方法也非常重要。如果每次都选取序列的第一个元素或最后一个元素作为主元,那么快排的效率会非常低。而随机选择主元则可以使得序列更加随机,从而提高快排效率。

2.3 插入排序

在对小规模的数据排序时,插入排序通常比快排更为高效,因为插入排序的常数项比快排小很多。因此,在快排中,当序列的长度小于一定的阈值时,可以使用插入排序的方式完成排序。

3. 归并排序的应用

归并排序是另一种非常高效、稳定的排序算法。与快排不同,归并排序是一种采用分治策略的排序算法,它的时间复杂度为O(nlogn)。

在实际应用中,归并排序经常被用来对链表进行排序,这是因为这种情况下,归并排序比快排更具有优势。

例如,我们需要对一个链表进行排序:

pythonCopy Code
class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def merge_sort(head: ListNode) -> ListNode: if not head or not head.next: return head mid = get_mid(head) right_head = mid.next mid.next = None left = merge_sort(head) right = merge_sort(right_head) return merge(left, right) def get_mid(head: ListNode) -> ListNode: slow = head fast = head while fast and fast.next: slow = slow.next fast = fast.next.next return slow def merge(left: ListNode, right: ListNode) -> ListNode: dummy = ListNode(-1) cur = dummy while left and right: if left.val <= right.val: cur.next = left left = left.next else: cur.next = right right = right.next cur = cur.next if left: cur.next = left else: cur.next = right return dummy.next

4. 常见的时间复杂度

排序算法的效率通常使用时间复杂度来衡量,时间复杂度是一种用于估算算法运行时间的方法。以下是几种常见的时间复杂度:

  • O(1):常数时间复杂度,表示算法的运行时间固定不变。
  • O(logn):对数时间复杂度,通常出现在二分搜索、树等算法中。
  • O(n):线性时间复杂度,表示算法的运行时间与输入的数据量n成正比。
  • O(nlogn):基于比较排序的算法通常都具备这种时间复杂度,如快排、归并排序。
  • O(n^2):冒泡排序、插入排序、选择排序等非常低效的算法通常具备这种时间复杂度。
  • O(n^3):高斯消元法等三重循环算法的时间复杂度为O(n^3)。

5. 总结

以上是关于排序算法衍生问题的学习笔记。其中,我们了解了稳定性的定义和意义、快速排序的优化、归并排序的应用以及常见的时间复杂度等内容。排序算法作为计算机科学中的一种基础算法,对于提高程序性能和开发效率非常重要。