排序总结

排序总结

总结了多种排序方式的基本原理、实现思路。

插入排序

基本原理:首先将由第一个数据元素组成的序列看成是有序的,然后将剩余的n-1个元素依次插入到前面的已排好序的子序列中去,使得每次插入后的子序列也是有序的。

根据往已经排好序的有序数据表中插入的不同方法,可以将插入排序分为:

  • 直接插入排序
  • 折半插入排序:利用二分查找法,快速地找到a[j]的插入位置。从而达到减少比较次数的目的。
  • 希尔排序:设待排序的对象序列有n个对象。首先取一个整数gap < n作为增量,将全部对象分为gap个子序列,所有距离为gap的对象放在同一个序列中,在每一个子序列中分别施行直接插入排序,然后缩小增量gap。重复上述的子序列划分和排序工作,直到最后取gap为1为止。

选择排序

首先,从n个元素中选出关键字最小的元素。再从剩下的(n-1)个元素中选出关键字最小的元素,依次类推,每次从剩下的元素序列中挑出关键字最小的元素,直至序列中最后只剩下一个元素为止。这样,把每次得到的元素排成一个序列,就得到了按非递减序排列的排序序列。

  • 直接选择排序:首先在所有元素中用逐个比较的方法选出最小元素,把它与第一个元素交换;然后在剩下的元素中再次用逐个比较的方法选出最小元素,把它与第二个元素交换;以此类推,直到所有元素都放入了正确的位置。
  • 堆排序:应用buildHeap对N个元素创建一个优先级队列,通过调用N次deQueue取出每个项,结果就排好序了。

交换排序

交换排序就是根据序列中两个数据元素的比较结果来确定是否要交换这两个数据元素在序列中的位置。

  • 冒泡排序:从头到尾比较相邻的两个元素,将小的换到前面,大的换到后面。经过了从头到尾的一趟比较,就把最大的元素交换到了最后一个位置。这个过程称为一趟起泡。然后再从头开始到倒数第二个元素进行第二趟起泡。经过了第二趟比较,又将第二大的元素放到了倒数第二个位置。依次类推,经过第n-1趟起泡,将倒数第n-1个大的元素放入第2个单元。
  • 快速排序:在待排序的序列中选择一个数据元素,以该元素为标准,将所有数据元素分为两组,第一组的元素均小于或等于标准元素,第二组的数据元素均大于标准元素。第一组的元素放在数组的前面部分,第二组的数据元素放在数组的后面部分,标准元素放在中间。这个位置就是标准元素的最终位置。这称为一趟划分。然后对分成的两组数据重复上述过程,直到所有的元素都在适当的位置为止。

归并排序

思想来源于合并两个已排序的有序表:顺序比较两者的相应元素,小者移入另一表中,反复如此,直至其中一表为空为止,将另一表中剩余结点自左至右复制到表C的剩余位置。

如果N=1,已排序;否则,对前一半和后一半分别调用归并排序,归并两个已排序的数组。

### 各类排序算法的时间和空间复杂度总结 #### 冒泡排序 冒泡排序是一种简单的排序算法,其平均时间复杂度为 O(n²),最坏情况下也是 O(n²)。然而,它的空间复杂度较低,仅为 O(1)。该算法具有稳定性[^1]。 #### 插入排序 插入排序同样属于简单排序算法之一,其平均时间复杂度也为 O(n²),但在最佳情况下的时间复杂度可以达到 O(n)。它也是一种原地排序算法,因此空间复杂度同样是 O(1)。值得注意的是,插入排序是一个稳定的排序算法。 #### 选择排序 选择排序通过多次扫描未排序部分找到最小值来完成排序过程。此算法的平均时间复杂度为 O(n²),并且不依赖于输入数据分布。尽管如此,它的空间复杂度仍然保持在 O(1) 的水平上。不过需要注意的是,选择排序并不具备稳定性。 #### 快速排序 快速排序采用分治策略实现高效排序,在理想条件下能够达到平均时间复杂度 O(n log n)。但是当分区操作不平衡时(例如已经接近完全有序的数据),可能会退化至最差性能 O(n²)。此外,由于递归调用栈的存在,其空间复杂度通常被估计为 O(log n);而在极端情况下可能上升到线性级别即 O(n)。 #### 堆排序排序利用二叉堆结构来排序处理,无论是在最好还是最坏的情况下都能维持固定的时间复杂度 O(n log n)。此同时,因为不需要额外分配内存资源用于存储临时变量或其他辅助信息等原因,所以它可以做到常量级的空间消耗——也就是 O(1)[^1]。 #### 归并排序 归并排序基于分而治之的思想构建而成,每次都将待排序序列分成若干子序列分别独立排序后再合并起来形成最终结果。这种做法使得即使面对大规模随机分布或者几乎已排好序的情况也能保证拥有良好的效率表现:总体来说都是 O(n log n) 的时间开销。但由于需要创建新的数组用来保存中间状态的缘故,因而增加了额外的需求——具体表现为占用约等于原始列表大小的一倍额外储存单元数量,从而导致整体空间复杂度变为 O(n)[^2]。 ```python def merge_sort(arr): if len(arr) <= 1: return arr mid = len(arr) // 2 left_half = merge_sort(arr[:mid]) right_half = merge_sort(arr[mid:]) merged_arr = [] while left_half and right_half: if left_half[0] < right_half[0]: merged_arr.append(left_half.pop(0)) else: merged_arr.append(right_half.pop(0)) merged_arr.extend(left_half or right_half) return merged_arr ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值