从顺序查找到直接插入排序

人盡茶涼 提交于 2019-12-01 11:44:46

从顺序查找到直接插入排序

无论从抽象过程还是具体实现代码来看,顺序查找是直接插入查找的基本组成元素。为什么这么说:

  • 排序要遍历所有元素
  • 从“未排序“数列中取出一个元素,插入到“已排序“数列中。需要在“已排序“数列中遍历到一个i,使得arr[i-1]<arr[i]<arr[i+1]。

需要两个基本的遍历过程。下面讨论算法的流程

直接插入排序的流程

首先脑海中要有一个基本模型:

【 {有序子序列} {当前待排序元素} {剩余待排序元素} 】

排序过程:
整个排序过程为n-1趟插入,即先将序列中第1个记录看成是一个有序子序列,然后从第2个记录开始,逐个进行插入,直至整个序列有序

注意:
有序子序列插入时,遍历不是从下标0开始,而是待排序元素的左边元素。

直接插入排序的性能

  • Space Complexity: S(n)=O(1)
  • Time Complexity: T(n)=O(\({n^2}\))
  • 一种稳定排序方法

设对象个数为n,则执行n-1趟最坏情况下:第 i 趟比较i次,移动i次
最大比较次数:\(\frac{n(n-1)}{2}\)
最大移动次数:\(\frac{n(n-1)}{2}\)
最好情况下:每趟只需比较 1 次,不移动 总比较次数为 n-1次。

code

code 1(C++ Iterative)

void insertionSort(int arr[], int n)
{
    int i, key, j;
    for (i = 1; i < n; i++) //从下标为1的位置开始遍历
    {
        key = arr[i];       //保存待排序元素的值
        j = i - 1;          //从待排序元素的前一个开始

        //找寻插入位置
        while (j >= 0 && arr[j] > key)  //循环条件1.不越界2.比key大
        {
            arr[j + 1] = arr[j];
            --j;
        }
        arr[j + 1] = key;               //移动key到待插入位置
    }
}

code 2(C++ Recursive)

如果熟悉了直接插入排序,与递归技巧,不难发现如下关系:

\1. Base Case: If array size is 1 or smaller, return.

\2. Recursively sort first n-1 elements.

\3. Insert last element at its correct position in sorted array.

void insertionSortRecursive(int arr[], int n)
{
    // Base case
    if (n <= 1)
        return;

    // Sort first n-1 elements
    insertionSortRecursive( arr, n-1 );
    // Insert last element at its correct position
    // in sorted array.
    int last = arr[n-1];
    int j = n-2;
    /* Move elements of arr[0..i-1], that are
      greater than key, to one position ahead
      of their current position */
    while (j >= 0 && arr[j] > last)
    {
        arr[j+1] = arr[j];
        j--;
    }
    arr[j+1] = last;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!