【数据结构】插入排序

来源:互联网 发布:java如何做一个表格 编辑:程序博客网 时间:2024/06/12 20:58

插入排序的基本思想是:每步将一个待排序的对象,按其关键字大小,插入到前面已经排好序的一组对象的适当位置上,直到对象全部插入为止。

简言之,边插入边排序,保证子序列中随时都是排好序的。

直接插入排序

新元素插入到哪里?在已形成的有序表中线性查找,并在适当位置插入,把原来位置上的元素向后顺移。

关键字序列T=(13,6,3,31,9,27,5,11),请写出直接插入排序的中间过程序列。

图示

关键字序列T= (21,25,49,25*,16,08),请写出直接插入排序的具体实现过程。*表示后一个25

假设该序列已存入一维数组V[7]中,将V[0]作为缓冲或暂存单元(Temp)。则程序执行过程为:

图示

图示

Void InsertSort (SqList  &L) ——教材P265{  // 对顺序表L做直接插入排序    for ( i=2; i<=L.length; ++i )       if (  LT (L.r[i].key, L.r[i-1].key) )                                          // “<“,需将L.r[i]插入有序子表         {  L.r[0] = L.r[i];          // 复制为哨兵            L.r[i] = L.r[i-1];            for ( j=i-2; LT(L.r[0].key, L.r[j].key); --j )               L.r[ j+1] = L.r[ j];   // 记录后移            L.r[ j+1] = L.r[0];     // 插入到正确位置          }}  // InsertSort
<?phpfunction insert_sort($arr) {    //从第二个元素开始,到最后一个元素都是这个需要排序的元素    for($i=1, $len=count($arr); $i<$len; $i++) {        //获得当前需要比较的元素值。        $tmp = $arr[$i];        //内层循环控制 比较 并 插入        for($j=$i-1;$j>=0;$j--) {            //$arr[$i];//需要插入的元素; $arr[$j];//需要比较的元素            if($tmp < $arr[$j]) {                //发现插入的元素要小,交换位置                //将后边的元素与前面的元素互换                $arr[$j+1] = $arr[$j];                //将前面的数设置为 当前需要交换的数                $arr[$j] = $tmp;            } else {                //如果碰到不需要移动的元素                //由于是已经排序好是数组,则前面的就不需要再次比较了。                break;            }        }    }    //将这个元素 插入到已经排序好的序列内。    //返回    return $arr;}$arr = array(21,25,49,25,16,8);$arr = insert_sort($arr);print_r($arr);

折半插入排序

在已形成的有序表中折半查找,并在适当位置插入,把原来位置上的元素向后顺移。

图示

Void  BInsertSort (SqList  &L)  // 折半插入排序{  for ( i=2;i<=L.length;++i )   {  L.r[0] = L.r[ i ];      // 将L.r [i] 暂存到L.r[0]      low=1;high=i-1while (low<=high)     //比较,折半查找插入位置      {  m=(low+high)/2// 折半         if (LT(L.r[0].key,L.r[m].key))  high=m-1//插入点在低半区         else   low=m+1// 插入点在高半区       } // while      for (j=i-1;j>=high+1;--j)  L.r [j+1] = L.r [j];// 记录后移      L.r [high+1] = L.r [0];                       // 插入    }  // for}  // BInsertSort

希尔(shell)排序(又称缩小增量排序)

基本思想:先将整个待排记录序列分割成若干子序列,分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。

技巧:子序列的构成不是简单地“逐段分割”,而是将相隔某个增量dk的记录组成一个子序列,让增量dk逐趟缩短(例如依次取5,3,1),直到dk=1为止。

优点:让关键字值小的元素能很快前移,且序列若基本有序时,再用直接插入排序处理,时间效率会高很多。

这里写图片描述

算法分析:开始时dk 的值较大,子序列中的对象较少,排序速度较快;随着排序进展,dk 值逐渐变小,子序列中对象个数逐渐变多,由于前面工作的基础,大多数对象已基本有序,所以排序速度仍然很快。

图示

void   ShellInsert (SqList &L,int dk) {//对顺序表L进行一趟增量为dk的Shell排序,dk为步长因子for(i=dk+1;i<=L.length; ++ i)//开始将r[i] 插入有序增量子表      if (r[i].key < r[i-dk].key)  {                r[0]=r[i];//暂存在r[0]       for( j=i-dk; j>0 &&(r[0].key<r[j].key); j=j-dk )     r[ j+dk ]=r[j];//关键字较大的记录在子表中后移        r[ j+dk ]=r[0];//在本趟结束时将r[i]插入到正确位置       }}
<?php//希尔排序(对直接插入排序的改进)function ShellSort(array &$arr){    $count = count($arr);    $inc = $count;    //增量    do {        //计算增量        //$inc = floor($inc / 3) + 1;        $inc = ceil($inc / 2);        for ($i = $inc; $i < $count; $i++) {            $temp = $arr[$i];    //设置哨兵            //需将$temp插入有序增量子表            for ($j = $i - $inc; $j >= 0 && $arr[$j + $inc] < $arr[$j]; $j -= $inc) {                $arr[$j + $inc] = $arr[$j]; //记录后移            }            //插入            $arr[$j + $inc] = $temp;        }        //增量为1时停止循环    } while ($inc > 1);}$arr = array(49,38,65,97,76,13,27,49,55,4);ShellSort($arr);var_dump($arr);
1 0
原创粉丝点击