排序——插入排序技术
插入排序的基本思想是:每次将一个待排序的记录,按其关键字的大小插入到它前面已经排好序的子表的适当位置;直到全部记录插入完成,整个表有序为止。
1、直接插入排序
直接插入排序是一种简单的插入排序方法,其基本思想为:在R1至Ri-1长度为i-1的子表已经有序的情况下,将Ri插入得到R1至Ri长度为i的子表有序(i=2……n)这样通过n-1趟之后,R1至Rn有序。
例如,对于以下序列(为简便起见,每一个记录只列出其排序码,用排序码代表记录):【10 18 20 36 60】25 30 18 12 56。其中,前5个记录组成的子序列是有序的,这时要将第6个记录插入到前5个记录组成的有序子序列中去得到一个含有6个记录的新有序序列。完成这个插入首先需要找到插入位置,即20<25<36,因此25应插入到记录20和记录36之间,从而得到以下新序列:
【10 18 20 25 36 60】30 18 12 56
可以看出直接排序的过程是顺序查找确定插入位置然后移动数据。两者可并行,从后往前搜索,搜索过程中同时移动数据。
初始状态下,认为长度为1的子表是有序的,因此对n个记录的表可从第2个记录开始直到第n个记录逐个向有序表中进行插入操作。
有以下排序表:36 20 18 10 60 25 30 18 12 56 ,按直接插入排序方法进行排序过程如下图示:
其中,R[0]的作用一方面做插入记录Ri的缓存单元,更重要的作用是它其监视哨的作用。关于监视哨作用在在顺序查找中有介绍参考算法之线性表查找技术 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)——通过监视哨使得查找插入位置时不必进行排序表的越界检测从而可以使比较次数约减少一半。
2、折半插入排序
直接插入排序的基本操作是想有序表中插入一个记录。在直接插入排序中,插入位置的确定是通过对有序表中关键码的顺序比较得到的。既然是有序表中确定插入位置,因此在寻找Ri的插入位置时就可以采用这边查找的方法来确定。利用这边查找方法查找插入位置,使得R[1]到R[i]有序,这种方法就是这边插入排序。
具体算法如下:
3、希尔排序
希尔排序又称缩减增量排序,其思想是:先选取一个小于n的整数d(称之为步长),然后把排序表中的n各记录分为d个组;从第一个记录开始,间隔为d的记录为同一组,各组内进行直接插入排序,一趟之后间隔d的记录是有序的,随着有序性的改善,减小步长d重复进行,直到d=1。使得间隔为1的记录有序,也就使整体达到了有序。
步长为1时就是前面所讲的直接插入排序。
例:设排序表关键码为:39 80 76 41 13 29 50 78 30 11 100 7 41 86;步长因子依次取5/3/1,其希尔排序过程如下图示:
通过图示可更清晰地理解为间隔步长d之间的数据进行比较。
设有t个增量,且增量序列已存放在数组d的d[0]到d[t-1]中,希尔排序的算法如下:
有个疑惑是,步长如何确定,随机取的??