zoukankan      html  css  js  c++  java
  • c语言进阶13-线性表之顺序表

    一、 ACM算法:顺序表的查找

    顺序表的查找指获取顺序表的第i个元素。对于线性表的顺序存储结构来说,如果我们要实现获取元素的操作(GetElem),即将线性表L中的第i个位置元素值返回。就程序而言,只要i的数值在数组下标范围内,就是把数组第i-1下标的值返回即可。

    #define OK 1

    # define ERROR 0

    # define TRUE 1

    # define FALSE 0

    typedef int Status;

    /* Status 是函数的类型,其值是函数结果状态代码,如OK等*/

    /*初始条件:顺序线性表L已存在,1≤i≤ListLength(L)*/

    /*操作结果:用e返回L中第i个数据元素的值*/

    Status GetElem(Sqlist L,int i, ElemType *e)

    {

              if(L.length==0 || i<1 | |i> L.length)

             return ERROR;

          *e=L.data[i-1];

          return OK;

    }

    注意这里返回值类型Status是一个整型,返回OK代表1,ERROR代表0

    二、 ACM算法:顺序表的修改

    由于顺序表中可以随机存取,将第i个元素修改为e的操作很简单。算法如下所示。

    Status UptElem(Sqlist L,int i, ElemType e)

    {

              if(L.length==0 || i<1 | |i> L.length)

             return ERROR;

          L.data[i-1]=e;

          return OK;

    }

    三、 线性表顺序存储结构的优缺点

      线性表顺序存储结构的优缺点如图所示:

     

    四、 顺序表的合并算法

    1. 1.        ACM算法:两个非递减有序的顺序表合并为一个非递减有序的顺序

    问题描述:已知顺序表la是一个非递减有序的顺序表,lb也是一个非递减有序的顺序表。将两个线性别合并,合并后的线性表lc也必须是非递减有序的。

    合并算法如下:

    #define MAX 100
    
    struct slist
    
    {
    
    int a[MAX];
    
    int len;
    
    };
    
    void main()
    
    {
    
    int i,p,q,r;
    
           struct slist lc;  //合并后的顺序表lc
    
    struct slist la={{12,12,15,17,19},5},lb={{12,13,13,16,18},5}; //定义顺序表la,lb并赋初值。
    
           lc.len=0;  //lc的初始长度为0
    
          
    
           printf("顺序表la的元素是:");
    
           for(i=0;i<la.len;i++)
    
           {
    
                  printf("%d	",la.a[i]);
    
           }
    
          
    
           printf("
    顺序表lb的元素是:");
    
           for(i=0;i<lb.len;i++)
    
           {
    
                  printf("%d	",lb.a[i]);
    
           }
    
          
    
           p=0;   //p标识la顺序表的下标
    
           q=0;   //q标识lb顺序表的下标
    
           r=0;   //r标识lc顺序表的下标
    
           while(p<la.len && q<lb.len)   //当两个两表都为到最后一个元素
    
           {
    
                  //将小的放到新顺序表中
    
                  if(la.a[p]<=lb.a[q])    
                  {
                         lc.a[r]=la.a[p];
                         r++;
                         p++;
                         lc.len++;
    
                  }
                  else
                  {
                         lc.a[r]=lb.a[q];
                         r++;
                         q++;
                         lc.len++;
                  }
           }
           while(p<la.len)   //la表未结束还有元素,将剩余元素加到lc表
           {
                         lc.a[r]=la.a[p];
                         r++;
                         p++;
                         lc.len++;
           }
    
           while(q<lb.len)  //lb表未结束还有元素,将剩余元素加到lc表
           {
                         lc.a[r]=lb.a[q];
                         r++;
                         q++;
                         lc.len++;
           }
           printf("
    合并顺序表后lc的元素是:");  //输出合并后的顺序表
           for(i=0;i<lc.len;i++)
           {
                  printf("%d	",lc.a[i]);
           }
    }

    该算法运行结果如图所示:

     

    五、 顺序表算法的时间复杂度分析:

    现在我们来分析一下,插入和删除的时间复杂度。

    先来看最好的情况,如果元素要插入到最后一个位置,或者删除最后一个元素,此时时间复杂度O(1),因为不需要移动元素的,就如同来了一个新人要正常排队,当人是排在最后,如果此时他又不想排了,那么他一个人离开就好了,不影响任何人。

    最坏的情况呢,如果元素要插入到第一个位置或者删除第一个元素,此时时间复杂度是多少呢?那就意味着要移动所有的元素向后或者向前,所以这个时间复杂度为O(n)。

    插入元素:在第i个位置插入元素需要移动n-i+1个元素,平均移动n/2个元素

    删除元素:在第i个位置删除元素需要移动n-i个元素,平均移动(n-1)/2个元素

    我们前面讨论过时间复杂度的推导,可以得出,平均时间复杂度还是O(n)。

    这说明什么?线性表的顺序存储结构,在存、读数据时,不管是哪个位置,时间复杂度都是O(1);而插入或删除时,时间复杂度都是O(n)。这就说明,它比较适合元素个数不太变化,而更多是存储数据应用。当然,它的优缺点还不只是这些。

    顺序表代码

    /* Note:Your choice is C IDE */
    #include "stdio.h"
    #define MAX 20
    typedef int type;
    
    typedef struct {
        type arr[MAX];
        int length;
    }sqlist;
    
    void fun(sqlist *L,type e)
    {
     int k;
     int i;
     printf("输入要插入的位置
    ");
     scanf("%d",&i);
     if(L->length==MAX){
         printf("线性表已满
    ");
     }   
     if(i<1||i>L->length+1){
         printf("输入错误");
     }
    /*查找
     printf("%d",L->arr[i-1]);*/
     /*修改
     L->arr[i-1]=e;*/
    /*添加 
    for(k=L->length;k<=i-1;k--){
         L->arr[k+1]=L->arr[k];
     }
     L->arr[i-1]=e;
     L->length++;*/
     /*删除
     for(k=i-1;k<L->length;k++)
    { L->arr[k]=L->arr[k+1];
    }
     L->length--;
    */
    }
    void main(){
       int i;
       sqlist L={{4,3,2,6,52,34},6};
    /*   for(i=0;i<6;i++){
           scanf("%d",&L->arr[i]);
           L->length=i+1;
       }*/
        for(i=0;i<L.length;i++){
           printf(" %d ",L.arr[i]);
           }
         fun(&L,20);
          
        for(i=0;i<L.length;i++){
           printf(" %d ",L.arr[i]);
           }
        }

    神州租车

    /* Note:Your choice is C IDE */
    #include "stdio.h"
    #include "stdlib.h"
    #include "string.h"
    double money=0.0;//定义全局变量账号金额
    void menu();//功能菜单
    void carinfor();//功能1
    void carcheck();//功能2
    void main()//主函数
    {
        int bh;
        menu();
        for(;;){
            printf("
    请输入主菜单功能标号:");
            scanf("%d",&bh);
            switch(bh){
                case 1:
                carinfor();
                break;
                case 2:
                carcheck();
                break;
                case 0:
                exit(0);
                default:
                printf("您输入的功能编号有误,请重新输入!");
                break;
                }
            }//无限循环
    }
    void menu()
    {
        printf("
    
    			══ 神州租车、中国租车领导者 ══
    ");
        printf("			1:神州专车信息
    ");
        printf("			2:神州专车结算
    ");
        printf("			0:退出
    ");
    }//菜单实现
    void carinfor()
    {
        char arr[20],brr[20],ch;//车名,人名,判断条件
        for(;;){
        printf("请选择车型:奥迪/东风本田:");
        fflush(stdin);
        gets(arr);
        if(strcmp(arr,"奥迪")!=0&&strcmp(arr,"东风本田")!=0){
            printf("暂时没有您需要的车型
    ");
            continue;
            }
        printf("请选择司机:吴亦凡/黄晓明:");
        fflush(stdin);
        gets(brr);
        if(strcmp(brr,"吴亦凡")!=0&&strcmp(brr,"黄晓明")!=0){
            printf("%s暂时没有上线
    ",brr);
            continue;
            }
        printf("是否确认提交订单Y/N:");
        ch=getchar();
        if(ch=='Y'){
            printf("
    本次专车出行,所选车型是;%s,专车司机是:%s",arr,brr);
            break;
        }else{
            printf("取消成功!");
            break;
        }
        }//for循环
    }//功能1实现
    void carcheck(){
        int number;//订单编号
        int distance,time;//里程,时间
        char checkstyle[20],choice;//支付方式,选择支付
        double money1;//充值金额
        double sum;//总金额
        printf("请输入订单编号;");
        scanf("%d",&number);
        printf("请输入本次行车里程;");
        scanf("%d",&distance);
        printf("请输入本次行车时间(分钟);");
        scanf("%d",&time);
        printf("请输入付款方式;");
        scanf("%s",checkstyle);
        if(strcmp(checkstyle,"支付宝")==0){
        printf("请选择充值金额:");
        scanf("%lf",&money1);
        printf("充值金额满100元得150元
    ");
        money+=money1;
        if(money>=100){
            money+=50;
        }
        
        printf("确认支付Y/N:");
        scanf(" %c",&choice);
        if(choice=='Y'){
            sum=20+(0.7*time)+(4.5*distance);
            if(money>=sum){
            printf("顾客您好,您的订单编号是%d,行车距离是%d里程,账号金额是%.2lf元,专车费用是%.2lf元,支付后账户余额是%.2lf元",number,distance,money,sum,money-sum);
            }else{
            printf("账号金额不足,请及时充值
    ");
            }
        }else if(choice=='N'){
        printf("取消支付成功!
    ");
        }else{
        printf("输入字符有误
    ");    
          }//是否支付
        }else{
        printf("支付方式无效!");
        }//关于支付宝的判断
    }//功能2 结束
  • 相关阅读:
    linux常用命令
    chattr无法删除某个文件
    centos如何卸载软件
    linux命令行下的ftp 多文件下载和目录下载
    yum -y upgrade 和 yum -y update 区别
    Pureftpd
    centos rar安装
    linux系统数据盘挂载教程
    anyexec
    _variant_t
  • 原文地址:https://www.cnblogs.com/TimVerion/p/11193450.html
Copyright © 2011-2022 走看看