十大排序算法——插入排序

直接插入排序

  • 基本思想:将序列第一个记录看作有序的,将后面的记录依次插入到已排好序的序列中。
  • 具体操作:假设第一个已经有序,对后面每个元素循环插入:如果从小到大排序,要插入的那个值如果大于末尾那个,就没必要插了。否则从末尾朝前找,直到那个值大于等于a[j]。然后插入位置当然是a[j+1]。
  • 代码实现:哨兵放在\(a[0]\)
    • 不放哨兵的话,就要判断边界a[i]<a[j] && j>=0
void insertsort(int a[], int n){
    for(int i=2;i<=n;i++){
        if(a[i]<a[i-1]){
            a[0] = a[i];
            for(int j=i-1; a[0]<a[j]; j--){
                a[j+1] = a[j];
            }
            a[j+1] = a[0];
        }
    }
}
  • 空间复杂度:\(O(1)\) 常数个辅助空间
  • 时间复杂度:插入元素\(n-1\)次,每次要比较和移动,其次数取决于待排序序列的原始状态
    • 最好情况:序列有序,每次插入,只需比较一次,不用移动,\(O(n)\)
    • 最坏情况:序列逆序,插入元素\(n-1\)次,总的比较次数最大\(\sum\limits_{i=2}^n{i}\) ,总的移动次数最大\(\sum\limits_{i=2}^n{(i+1)}\)
    • 平均情况:元素随机,期望值可以取最好最坏的平均,总的比较和移动次数约为\(n^2/4\)
    • 由此:直接插入排序算法时间复杂度为\(O(n^2)\) 实际看代码也能看出
  • 稳定性:稳定排序
    • 因为是从后往前比较再移动,所以遇到相同元素就肯定停下来了,所以相对位置不会改变
  • 适用性:顺序和链式(链式时也可以从后往前查找),大部分排序都只适合顺序

折半插入排序

  • 可以优化的地方:在有序序列中查找一个比那个值更小的时,可以用二分

猜你喜欢

转载自www.cnblogs.com/doragd/p/11291773.html