排序算法分析 --- 插入排序

一 算法分析

假设有n个元素,现在要把这些元素按照从小到大的顺序进行排序,那么算法步骤如下,

  1. 把n个元素分成两个区域,即有序区和无序区,其中有序区包含第0个元素,无序区包含剩下n-1个元素
    在这里插入图片描述

  2. 从无序区中拿出最左边的元素(也就是第1个元素),以从右向左的方式和有序区里的元素进行比较

  3. 如果比较时该元素(来自无序区)比当前进行比较的有序区元素小,那么就把当前进行比较的有序区元素放到右边的位置上

  4. 重复步骤3,直到该元素(来自无序区)比当前进行比较的有序区元素大,或者和有序区里所有的元素都比较了,那么就把该元素插入到步骤3中有序区元素右移空出来的位置上,此时该轮比较操作就结束了

  5. 重复步骤2,直到无序区里所有的元素都被放到了正确的位置,那么排序结束


二 C代码

void insertionSort(int arr[], int len)
{
    int element = 0;

    for (int index = 1; index < len; ++index)
    {
        element = arr[index]; // 暂存无序区的元素 

        int start = index - 1; // 有序区最后一个元素的索引
        for (; start >= 0; --start) // 从右向左遍历有序区
        {
            // 如果正在比较的有序区元素比element大,就把有序区元素右移一个位置
            if (arr[start] > element) 
                arr[start+1] = arr[start];
            else // 如果正在比较的有序区元素 <= element,那么遍历就结束了
                break;
        }

        arr[start+1] = element; // 把无序区元素插入到有序区元素右移空出来的位置
    }
}

三 Tip

整个算法有些地方比较让人迷惑,只要理解了这些迷惑点,就理解这个算法了。如下,

  • 假设要排序的无序区元素叫A,有序区最后一个元素叫B,第一次比较时,如果A比B小,那么就把B右移一个位置,占据原本属于A的位置,此时A的值是暂存在变量element里的,所以B右移后不会对A产生影响,而且原本属于B的位置就空出来了
  • 继续往左去比较,如果A比正在比较的有序区元素大,那么就把A放到之前B右移空出的位置,这样A就排好序了
  • 另外,如果第一次比较时A比B大,那么B就不需要右移,而A就直接插入到A本身的位置上就可以了

四 总结

理解插入排序的关键点有两个:

  1. 是有序区和无序区的划分
  2. 每次比较时如果有序区元素小于无序区元素,无序区元素右移一个位置,空出当前位置,留着放置无序区元素,或者给下一个有序区元素右移

如果有写的不对的地方,希望能留言指正,谢谢阅读。

猜你喜欢

转载自blog.csdn.net/whahu1989/article/details/83212333