算法原理:
始终将两个序列分为两个部分:有序前缀,待排序区间。反复迭代,取出未排序数据首元素,在已排序序列中从后向前扫描,找到相应位置并插入。
不变形:任意时刻,对于当前元素e=s[r],前缀区间s(0,r)总有序。
适应范围:向量或者链表等任何序列结构体
实际应用:打牌的时候排列扑克
算法实现:
template <typename T> //valid(p)&&rank(p)+n<_size
void List<T>::insertionSort (ListNodePtr p, int n )
{
for ( int r = 0; r < n; r++ ) //r也是有序序列的计数
{
ListNodePtr nd = search(p->data, r, p );//查找位置节点
insertAfter( nd, p->data ); //插入位置节点
p = p->succ; //转向下一节点
remove ( p->pred );//
}
}
需要解释的是,查找算法,找到的是在前缀中不大于(小于等于)e的位置。
template <typename T>//有序列表内节点p的n个(真)前驱中,找到不大于e的最后者
ListNodePtr List<T>::search(T const &e,int n,ListNodePtr p) const
{
ListNodePtr pCur = p;
while (n-- >= 0)
{
pCur = pCur->pred;
if (e >= pCur->data)
{
return pCur;
}
}
return NULL;
}
算法分析:
算法名称 | 时间复杂度(平均) | 时间复杂度(最坏) | 时间复杂度(最好) | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
冒泡 | O() | O() | O() | 0(1) | 稳定 |
算法时间复杂度:
n + (n-1) + (n-2) + ...+2+1
算法优化:折半插入排序、表插入排序