• 搜索有序链表的四种算法,并比较优劣


          如何在一个有序链表中找到目标值有很多种算法,常用的有时间为O(n)的确定性算法A,时间为O(√n)的确定性算法B,时间为O(n)的概率算法C,在这几种算法中,算法B效率最高,为进一步提高算法效率,写一Sherwood算法C,与算法A, B, D比较,给出实验结果。

    首先定义了一个普通的有序链表,再定义一个特殊的有序链表,通过A、B、C、D四种算法在两个链表上的不同表现,得出结论。

    程序源代码(C语言描述):

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <math.h>
    #define targ 18
    
    int n=20,head=3,head1=0;//定义静态链表
    int val[20]={2,17,11,1,7,15,20,3,19,14,8,5,18,10,13,6,4,12,16,9};
    int ptr[20]={7,12,17,0,10,18,100,16,6,5,19,15,8,2,9,4,11,14,1,13};
    int val1[20]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
    int ptr1[20]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,100};
    
    void main()
    {
    printf("普通有序静态链表0\n");
    printf("val[20]={2,17,11,1,7,15,20,3,19,14,8,5,18,10,13,6,4,12,16,9};\n");
    printf("ptr[20]={7,12,17,0,10,18,100,16,6,5,19,15,8,2,9,4,11,14,1,13};\n");
    printf("-----------------------------------------------------------\n");
    printf("特殊有序静态链表1\n");
    printf("val1[20]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};\n");
    printf("ptr2[20]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,100};\n");
    printf("-----------------------------------------------------------\n");
    
    printf("A算法在链表0中查找%d:",targ);
    printf("目标位置i=%d\n",A(targ));
    
    printf("B算法在链表0中查找%d:",targ);
    printf("目标位置i=%d\n",B(targ));
    
    printf("C算法在链表0中查找%d:",targ);
    printf("目标位置i=%d\n",C(targ));
    
    printf("D算法在链表0中查找%d:",targ);
    printf("目标位置i=%d\n",D(targ));
    printf("-----------------------------------------------------------\n");
    
    printf("A算法在链表1中查找%d:",targ);
    printf("目标位置i=%d\n",A1(targ));
    
    printf("B算法在链表1中查找%d:",targ);
    printf("目标位置i=%d\n",B1(targ));
    
    printf("C算法在链表1中查找%d:",targ);
    printf("目标位置i=%d\n",C1(targ));
    
    printf("D算法在链表1中查找%d:",targ);
    printf("目标位置i=%d\n",D1(targ));
    }
    
    
    int search(int x,int i)
    {int k=0;//记录查找的次数
        while(x>val[i])
        {
            i=ptr[i];
            k++;
        }
        printf("共查找了%d次\n",k+1);
        return i;
    }
    
    int A(int x) //时间为O(n)的确定性算法
    {
        return search(x,head);
    }
    
    int B(int x) //时间为O(√n)的确定性算法
    {
        int j,y,i=head;
        int max=val[i]; //max初值是表val中的最小值
        for(j=0;j<sqrt(n);j++) //在val的前√n个数中
                               //找不大于x的最大整数y相应的下标i
        {
            y=val[j];
            if(max<y&&y<=x)
            {
                i=j;
                max=y;
            }
        }
        return search(x,i); //从y开始继续搜索
    }
    
    int C(int x)  //在算法B基础上改进的sherwood算法
    { int j,k,i=head;
      int max=val[i];  
      srand( (unsigned)time(0));
      for(j=0;j<sqrt(n);j++)
      {k=rand()%n;    //在0-n中取√n个随机数作为下标,将这些下标对应的val值
                      //与x比较,找出不大于x的最大整数相应的下标i
         if(max<val[k]&&val[k]<=x)
         {i=k;
          max=val[k]; 
         }
      }
      return search(x,i);
    }
    
    
    int D(int x)  //时间为O(n)的概率算法
    {
        
        int i=rand()%n;
        int y=val[i];
        if(x<y)
            return search(x,head);
        else if(x>y)
            return search(x,ptr[i]);
        else
            return i;
    }
    
    int search1(int x,int i)
    {int k=0;
        while(x>val1[i])
        {
            i=ptr1[i];
            k++;
        }
        printf("共查找了%d次\n",k+1);
        return i;
    }
    
    int A1(int x)
    {
        return search1(x,head1);
    }
    
    int B1(int x)
    {
        int j,y,i=head1;
        int max=val1[i];
        for(j=0;j<sqrt(n);j++)
        {
            y=val1[j];
            if(max<y&&y<=x)
            {
                i=j;
                max=y;
            }
        }
        return search1(x,i);
    }
    
    int C1(int x)
    { int j,k,i=head1;
      int max=val1[i];  
      srand( (unsigned)time(0));
      for(j=0;j<sqrt(n);j++)
      {k=rand()%n;
         if(max<val1[k]&&val1[k]<=x)
         {i=k;
          max=val1[k]; 
         }
      }
      return search1(x,i);
    }
    
    
    int D1(int x)
    {
        
        int i=rand()%n;
        int y=val1[i];
        if(x<y)
            return search1(x,head1);
        else if(x>y)
            return search1(x,ptr1[i]);
        else
            return i;
    }

    运行结果:

    可以取不同的targ 多运行几次。

    结论:

    1:时间为O(n)的确定算法A所需时间最长,效率最低

    2:时间为O(n)的概率算法D随机性很大,对同一target,算法效率有时很高,有时很低。

    3、时间为O(√n)的确定性算法B和在算法B基础上改进的sherwood算法C在普通有序链表中表现较好,旗鼓相当,但当遇到特殊有序表(val[]本身有序)时,算法效率急剧下降。而改进的sherwood算法C却依旧保持极高的效率。说明sherwood算法虽然并不比同类型确定性算法快,但他消除了最坏实例的影响。

  • 相关阅读:
    对流程和规范的思考
    我的一小时面试指南
    安全扫描工具nikto简单使用
    测试的角色
    测试的窘境
    关于重连测试的一点研究
    ETCD高可用特性学习
    Cgroup和Namespace在测试中的使用(下)
    单循环列表的删除前驱结点
    指针常量字符串
  • 原文地址:https://www.cnblogs.com/yuzeren48/p/2736235.html
Copyright © 2020-2023  润新知