• 内部排序->插入排序->其它插入排序->2-路插入排序


    文字描述

      在折半插入排序的基础上进行改进, 另设一个和待排序序列L相同的数组D, 首先将L[1]赋值给D[0], 数组D中数据是已经排好序的, first指向最小值下标,final指向最大值下标。初始时,first和final值都为0。之后将L的第二个元素开始依次和D[0]比较,大于D[0]的插入到D[0]之后的序列,小于D[0]的插入到D[0]之前的序列;这里可以将数组D想象成一个循环的圆。

    示意图

    算法分析

      时间复杂度为n*n, 辅助空间为n,是稳定的排序方法。 

      二路插入排序和折半插入排序比,只是可以大概率的减少移动的次数,但不能绝对避免,当待排序序列中的第一个数据就是最小值或者最大值时,2-路插入排序将完全失去它的优越性。

    代码实现

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 #define EQ(a, b) ((a) == (b))    //数a和数b相等则为True,否则为False
      5 #define LT(a, b) ((a) <  (b))    //数a小于数b则为True
      6 #define LQ(a, b) ((a) <= (b))    //数a小于或等于数b则为True
      7 
      8 #define MAXSIZE 20    //待排序数的最多个数
      9 typedef int KeyType;    //定义待排序数据的关键字类型为int
     10 typedef int InfoType;    //定义待排序数据的其他信息类型为int
     11 typedef struct{
     12     KeyType key;        //关键字
     13     InfoType otherinfo;    //其他数据项
     14 }RedType;    //记录类型
     15 
     16 typedef struct{
     17     RedType r[MAXSIZE+1];    //r[0]闲置或用作哨兵单元
     18     int length;    //顺序表长度
     19 }SqList;    //顺序表类型
     20 
     21 /*
     22  * 顺序打印序列表L中的关键字
     23  */
     24 void PrintList(SqList L){
     25     int i = 0;
     26     printf("len:%d; data:", L.length);
     27     for(i=1; i<=L.length; i++){
     28         printf("%d ", L.r[i].key);
     29     }
     30     printf("
    ");
     31     return ;
     32 }
     33 
     34 #define DEBUG 
     35 
     36 /*
     37  * 2-路插入排序算法的实现
     38  *
     39  * @param 
     40  *        SqList *L : 待排序的顺序表
     41  */
     42 void TwoInsertSort(SqList *L)
     43 {
     44     //数组D是和L中关键字列表长度相同的辅助数组
     45     RedType D[MAXSIZE] = {0};
     46     //将L中第一个数据存入D[0]
     47     D[0] = L->r[1];
     48 
     49     int i = 0, j = 0, n = L->length;
     50     //first表示D中最小值下标,final表示D中最大值下标
     51     int first = 0, final = 0;
     52     int k = 0;
     53 #ifdef DEBUG
     54     for(j=0; j<n; j++){
     55         printf("%d  ", D[j].key);
     56     }
     57     printf("
    the %d lap:fist=%d, final=%d
    
    ", i, first, final);
     58 #endif
     59 
     60     for(i=2; i<=L->length; i++){
     61         if(LT(L->r[i].key, D[first].key)){
     62             // 待插入元素比最小的元素小 
     63             first = (first-1+n)%n;
     64             D[first] = L->r[i];
     65         }else if(LT(D[0].key, L->r[i].key)){
     66             // 待插入元素比最大的元素大
     67             final = (final+1)%n;
     68             D[final] = L->r[i];
     69         }else{
     70             // 待插入元素处在最小元素和最大元素中间
     71             // 采用直接插入排序的方法,插入到数组D中合适的位置
     72             k = (final+1)%n;
     73             while(LT(L->r[i].key, D[(k-1+n)%n].key)){
     74                 D[(k+n)%n] = D[(k-1+n)%n];
     75                 k = (k-1+n)%n;
     76             }
     77             D[(k+n)%n] = L->r[i];
     78             final = (final+1)%n;
     79         }
     80 #ifdef DEBUG
     81         for(j=0; j<n; j++){
     82             printf("%d  ", D[j].key);
     83         }
     84         printf("
    the %d lap:fist=%d, final=%d
    
    ", i, first, final);
     85 #endif
     86     }
     87     //将排序记录复制到原来的顺序表里 
     88     for(j=0; j<n; j++){
     89         L->r[1+j] = D[first];
     90         first = (first+1)%n;
     91     }
     92 }
     93 
     94 int  main(int argc, char *argv[])
     95 {
     96     if(argc < 2){
     97         return -1;
     98     }
     99     SqList L;
    100     int i = 0;
    101     for(i=1; i<argc; i++){
    102         if(i>MAXSIZE)
    103             break;
    104         L.r[i].key = atoi(argv[i]);
    105     }
    106     L.length = (i-1);
    107 
    108     TwoInsertSort(&L);
    109     PrintList(L);
    110     return 0;
    111 }
    2-路插入排序

    运行

    [jennifer@localhost Data.Structure]$ ./a.out 12 5 7 4 5 3 45 76
    12 0 0 0 0 0 0 0 
    the 0 lap:fist=0, final=0

    12 0 0 0 0 0 0 5 
    the 2 lap:fist=7, final=0

    7 12 0 0 0 0 0 5 
    the 3 lap:fist=7, final=1

    7 12 0 0 0 0 4 5 
    the 4 lap:fist=6, final=1

    5 7 12 0 0 0 4 5 
    the 5 lap:fist=6, final=2

    5 7 12 0 0 3 4 5 
    the 6 lap:fist=5, final=2

    5 7 12 45 0 3 4 5 
    the 7 lap:fist=5, final=3

    5 7 12 45 76 3 4 5 
    the 8 lap:fist=5, final=4

    len:8; data:3 4 5 5 7 12 45 76 
    [jennifer@localhost Data.Structure]$

  • 相关阅读:
    arduino远程刷新(烧录)固件
    通过语音控制电灯、空调、房门。芝麻开门
    arduino红外遥控库IRremote的IRsend类sendRaw函数溢出问题及其解决方法
    64位sql server 如何使用链接服务器连接Access
    Linux常用命令汇总
    常用的排序算法总结
    MongoDB数据库常用SQL命令 — MongoDB可视化工具Robo 3T
    SynchronousQueue队列程序的执行结果分析
    输入编码,自动匹配并输出相对应的名称
    linux五种IO模型与事件驱动模型
  • 原文地址:https://www.cnblogs.com/aimmiao/p/9346938.html
Copyright © 2020-2023  润新知