一、插入排序:INSERTION-SORT

1、适用范围:

 which is an efficient algorithm for sorting a small number of elements.

对于少量元素的排序,插入排序是一种高效的算法。

2、原理:

Insertion sort works the way many people sort a hand of playing cards. We start with an empty left hand and the cards face down on the table.

We then remove one card at a time from the table and insert it into the correct position in the left hand.

To find the correct position for a card, we compare it with each of the cards already in the hand, from right to left,

插入排序原理和玩纸牌一样,我们原本左手中没有牌,牌都在桌子上放着,我们从桌子上取出一张牌,并插入到左手中。

第一次插入为直接插入,因为此时我们手中没牌,等到第二次插入时,我们和第一次插入的牌比较,将大的放在右边,小的放在左边。

第三次插入则是将从桌子上取的牌,和手中的每一张牌以从右往左的顺序比较,将牌插入到合适的位置。

3、插入排序伪代码:


说明:j代表索引,此处索引从1开始,而非0,插入时从第二个数字开始插入;

      循环不变式(上述插入排序的不变式为A[1..j-1]):用于帮助理解算法正确性,必须证明其三个性质:

               (1)、初始化:即循环不变式在第一次迭代之前,应该是正确的;如上述插入排序,初始化时,A[1..j-1]为A[1],已排好序。
               (2)、保持:在循环的某一次迭代开始之前不变式是正确的,那么下一次迭代开始之前,应该也是正确的;如上述插入排序,每次迭代,A[1..j-1]都是已排序好的子数组。
               (3)、循环结束时,是否达到要求的排序或者其他效果;如上述插入排序,循环结束时,A[1..j-1]就是整个已经排好序的数组。

习题:

  2.1-1 以图2-2模型为例,说明插入排序在数组A=[31,41,59,26,41,58]上的执行过程。


  2.1-2 重写Insert-sort,使之按照非升序(而非非降序)排序

 INSERT_SORT (A)

for j =2  to A.length //对第二个数开始之后的数字循环

     key = A[j];//将当前循环的数字赋值给临时key变量

     i = j-1;//得到已排好序的子数组的最大边界

     while(i>0 and A[i]<key) //拿当前循环的数字key和每一个已排序数组的数字比较,非升序则是已排序好的数组中只要比key小,都和key的位置调换。

         A[i+1] = A[i];//移动已排序好的数组中被比较的数字到当前循环数字的位置(其位置逐个位置变动)

         i--;//

     A[i+1]=key;//将key放置到最终合适的位置上。

2.1-3  考虑下面的查找问题

 输入:一列数A=(a, a2,..., an)和一个值v。

 输出:下标i,使得v=A[i],或者当v不在A中出现时为NIL。

 写出针对这个问题的线性查找的伪代码,它顺序的扫描整个序列以查找v,利用循环不变式证明算法的正确性。确保所给出的循环不变式满足三个必要的性质。

伪代码(可能不符合标准,但基本意思表达):

String res = NIL;

for i=0 to A.length

   if(A[i] == v) res += i;;

print res;

初始化:一开始比较之前,res为NIl,符合要求。

保持:在循环比较时,每次比较,当前循环的数组元素若和v相等则会输出,不等则不对res做操作(仍未NIL),符合要求。

结果:当循环结束时,res里保存了和v相等的所有数组元素的下标值,若全部不等则仍未NIl,符合。

2.1.4

有两个各存放数组A和B的n位二进制数,考虑他们的相加问题,两个整数的和以二进制形式存放在具有n+1个元素的数组C中,请给出这个问题的形式化描述,并写出伪代码。。

 解答:

 carry = 0; //进位值

  for i =0 to n

    temp = A[i]+B[i]+carry;//保存相同位数相加的结果

    C[i] = temp %2; //取余

    carry = temp /2;//取整

C[n+1] = carry;//C的最高位即是最后一次进位值

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐