结构推理 对于直接插入排序、直接选择排序、冒泡排序、Shell排序、快速排序和堆排序这6种算法进行上机实习。要求:
   (1)被排序的对象由计算机随机生成,长度分别取20,100,500三种。
   (2)算法中增加比较次数和移动次数的统汁功能。
   (3)对实习的结果作比较分析。
【正确答案】(1)算法
   各种算法的思想具体请参见教材,其中有详细地说明,这里不再赘述。
   (2)程序实现
   此处将6种算法的实现写成6个函数,放在一个程序中。
   每个函数中添加Pmove和Pcompare的指针参数记录移动和比较次数。由于有时要递归调用,所以函数内部比较和移动的次数加上调用的初始值才是实际的值。主函数中调用时,每次要将这两个参数的初值设为0。
   考虑到随机性,每次排序都重新生成新的数组。各种排序算法均按递增序排列。
   完整程序:(略)
   (3)实习结果比较分析
   排序结果:
   n=20
   the origion record:
   46   30    82    90    56    17    95    15   48   26
   4    58    71    79    92    60    12    21   63   47
   直接插入排序:
   4    12    15    17    21    26   30    46    47    48
   56   58    60    63    71    79   82    90    92    95
   move:132  compare:112
   the origion record:
   19   41   90   85    14     9    52    71    79    16
   81   51   95   93    34    10    79    95    61    92
   直接选择排序:
   9    10    14    16    19    34    41    51    52    61
   71   79    79    81    85    90    92    93    95    95
   move:54 compare:190
   the origion record:
   89   88    66    64    92    63    66    64    39    51
   27   0     95    12     8    66    47    42    74    69
   冒泡排序:
   0     8    12    27    39   42   47   51    63    64
   64   66    66    66    69   74   88   89    92    95
   move:351  compare:175
   the origion record:
   89  83   66   41   90   78   65   79   90   33
   53  29   85   22   33   37   36   68   60   58
   Shell排序:
   22    29    33    33    36   37   41    53    58    60
   65    66    68    78    79   83   85    89    90    90
   move;161  compare:87
   the origion record:
   36   60   42   42    67   15   16    18    56   79
   8    59   61   97    55   81   75    40    90    1
   快速排序:
   1    8   15   16   18   36   40   42   42   55
   56  59   60   61   67   75   79   81   90   97
   move:24 compare:64
   the origion record:
   37   35   43   67   12   11    33   93   54   53
   26   18   86   70   84   14    31   99   86   30
   堆排序:
   11   12   14   18   26   30   31   33   35   37
   43   53   54   67   70   84   86   86   93   99
   move:173  compare:122
   n=100,n=500的排序结果省略。
   (4)比较和移动次数的对比分析
   1)比较次数
排序算法 n=20 n=100 n=500 理论分析次数
直接插入排序 112 2588 62859 O(n2)
直接选择排序 190 4950 124750 O(n2)
冒泡排序 175 4830 124729 O(n2)
Shell排序 87 848 6256 O(n1.3)
快速排序 64 617 4957 O(nlog2n)
堆排序 122 1023 7417 O(nlog2n)

   2)移动次数
排序算法 n=20 n=100 n=500 理论分析次数
直接插入排序 132 2685 63352 O(n2)
直接选择排序 54 285 1479 O(n2)
冒泡排序 351 7752 187080 O(n2)
Shell排序 161 1391 10016 O(n1.3)
快速排序 24 207 1616 O(nlog2n)
堆排序 173 1065 6528 O(nlog2n)

   结论:从n=500的测试结果可以看出,对随机输入的排序码花费的时间代价有以下的结论。
   比较次数:快速排序<Shell排序<堆排序<直接插入排序<冒泡排序<直接选择排序。
   移动次数:直接选择排序<快速排序<堆排序<shell排序<直接插入排序<冒泡排序。
   如果以一次移动相当于两次比较的时间计算,折合成移动次数的时间代价如下表所示:
【答案解析】上机实习的一个重要目的是把课本中学到的知识加以实践。本题是一个典型的例子。所有算法都在书中提供,甚至源代码都可以让学生复制以节省不必要的重复录入时间。学生的任务是深入地理解算法的思想,在实践中体会算法的特点,包括那些在理论上没有深入比较的算法之间的差别。例如,对于时间代价同样为nlog2n的算法在实践中还是会有很大差别。