C++ 数据结构(三)列表(5)插入排序

本文详细探讨了C++中列表的插入排序,包括构思、实例、实现及性能分析。插入排序在最好情况下,时间复杂度为O(n),最坏情况下为O(n^2),平均性能为O(n^2)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

来源:我的博客站 OceanicKang |《C++ 数据结构(三)列表(5)插入排序》

上一篇:《C++ 数据结构(三)列表(4)选择排序》

构思

1.png

始终将序列看成两部分:

SortedUnsorted
L[0, r)L[r, n)

【初始化】 |S| = r = 0,空序列无所谓有序

【迭代】关注并处理 e = L[r],在 S 中确定 适当位置 插入 e,得到有序的 L[0, r]

【不变性】随着 r 的递增,L[0, r) 始终有序,直到 r = nL 即整体有序

实例

2.png

实现

// 对列表中起始于位置 p 的连续 n 个元素做插入排序,valid(p) && rank(p) + n <= size
template <typename T>
void List<T>::insertionSort(Posi(T) p, int n) {
    for (int r = 0; r < n; r++) { // 逐一引入各节点,由 S(r) 得到 S(r+1)
        insertAfter(search(p -> data, r, p), p -> data); // 查找 + 插入
        p = p -> succ; remove(p -> pred); // 转向下一节点
    } // n 次迭代,每次 O(r + 1)
} // 仅使用 O(1) 辅助空间,属于就地算法

性能分析

最好情况:完全(或几乎)有序。每次迭代,只需 1 次比较,0 次交换,累计 O(n) 时间

最坏情况:完全(或几乎)无序。每次迭代,需 O(k) 次比较,1 次交换,累计 O(n^2) 时间

平均性能

3.png

假定:各元素的取值遵守均匀、独立分布

于是:平均要做多少次元素比较?

考查:L[r] 刚插入完成的那一时刻(穿越?)

试问:此时的有序前缀 L[0, r] 中,哪个元素是此前的 L[r]

观察:其中 r + 1 个元素 均有可能,且概率均等于 1/(r + 1)

因此,在刚完成的这次迭代中,为引入 S[r] 所花费时间的数学期望为

$ [r + (r - 1) + \cdots + 3 + 2 + 1 + 0] / (r + 1) + 1 = r / 2 + 1 $

于是,总体时间的数学期望 = $ [0 + 1 + \cdots + (n - 1)] / 2 + 1 = O(n^2) $

下一篇:《C++ 数据结构(四)栈与队列(1)栈接口与实现》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值