插入排序

  直接插入排序

 

  每次将一个待排序的记录,按其关键字大小插入到前面的已经排好的子表中的适当的位置。直到全部记录插入完成为止。


插入排序 —— 直接插入排序 + 折半插入排序

看图说话,如图所示:

  一共有 N 个记录 ,放在 R 列表中 R[0,n-1]

  在排序过程中的某一时刻,呈现了如果所示的场景。

  其中:

    浅绿色为 已经排好序的 部分 称之为 有序区 R[0,i-1]

    橘色为 当前元素 

    橘色+ 蓝色 为尚未排序的 部分 称之为 无序区 R[i,n-1]

 

   我们排序的时候,总是将无序区的第一个记录,放到有序区的合适位置,使有序区长度 +1 ,形成新的有序区 R[0,i]

 

  说人话:

    其实最开始的时候,我们就假设该列表的的有序区内仅含有一个记录。即列表的第一个记录 R[0]

    其余所有记录都位于无序区,即R[1,n-1] 均为无序区。

    开始排序:

      从无序区拿第一个元素和有序区的最后一个元素比较,即R[1] 和R[0] 比较,如果 R[1] 小于R[0],那么R[0]向后移动一位,占据R[1]的位置。将原R[1] 插入到R[0] 前面。即原来R[0]的位置。有序区长度+1;如果R[1] 大于R[0],两个记录保持不变。有序区长度依旧+1。有序区编程R[0],R[1]

      经过过上一步的比较、排序,现在的无序区的第一个记录就变成了R[2],然后将R[2] 提出来,依次和它前面的记录进行比较,如果发现比R[2]小的记录,那么将R[2]插入到该记录后面。假设一种情况:R[2] 首先和R[1]比较,发现R[2] 大于R[1] 于是将R[1]向后移动一位,注意:先别急着把R[2]插入到R[1]的前面。因为你不知道R[0]和R[2]的关系。所以,继续用R[2]和R[0]比较,假设R[0]小于R[2]了,那么这个时候,再将R[2]放入到R[0]的后面即R[1]的位置。

      。。。。

      直到所有的记录都这样插入一个遍。

    插入排序 —— 直接插入排序 + 折半插入排序

 

  可以这样理解,有一个平台上,上面都是排列好的娃娃(左边一排排)。还有一对杂乱无章的娃娃(右侧圆圈),无乱的堆放在一起。你操作着头顶的机械手,每次从右边的那一大堆的娃娃里面夹起一个,然后向左移动。在平台上,每看到一个娃娃,那么就将机械手里夹着的娃娃和现在你看到的平台上的娃娃那个更大,如果发现平台上的娃娃更大,那么就继续向左移动机械手,看平台上下一个娃娃,如果还是平台上的娃娃大,那么继续向左移动机械手。。。知道你发现机械手的娃娃比平台上的那个娃娃大(假设叫 z ),那么就将机械手上的娃娃放到 z 的后面。其他的比你手里的娃娃大的那些娃娃,在你每一次比较完毕之后,都被人向右移动了一些距离。于是,刚好就给你流出了放置娃娃的空间。

 

 

代码如下:

def insert_sort(A):
    n = len(A)           # 序列A 的长度
    for  i in range(1,n):  # 从序列A 的第二个元素开始比较。即下标从 1 开始。
        temp = A[i]     # 设置一个变量,承接当前的 元素的值
        j = i -1        #  有序区的最后一个元素的索引,每次比较都是从和该位置元素比较开始,逐渐向左推进。
        while j>=0 and temp<A[j]:  # j 指代 每个有序区元素的索引,所以j 不能小于0。 当 当前元素 小于 要比较的元素时,进行while循环。
            A[j+1]=A[j]   # 将比当前元素大的有序区的元素向右移动一个位置。
            j -= 1  # 不着急放下当前元素,而是继续查看在j 元素之前是否还有元素,且该元素和当前元素相比,哪个大
        A[j+1] = temp  # j前面已经没有元素了,或者是那个元素小于当前元素。那么将当前元素放到那个元素的后面。
    return A



a = [34,1,4,3,6,8,89,23,12]
print(insert_sort(a))
View Code

相关文章: