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算法:两个非递减有序的顺序表合并为一个非递减有序的顺序
  2.  

问题描述:已知顺序表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\t",la.a[i]);

       }

      

       printf("\n顺序表lb的元素是:");

       for(i=0;i<lb.len;i++)

       {

              printf("%d\t",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("\n合并顺序表后lc的元素是:");  //输出合并后的顺序表
       for(i=0;i<lc.len;i++)
       {
              printf("%d\t",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("输入要插入的位置\n");
 scanf("%d",&i);
 if(L->length==MAX){
     printf("线性表已满\n");
 }   
 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("\n请输入主菜单功能标号:");
        scanf("%d",&bh);
        switch(bh){
            case 1:
            carinfor();
            break;
            case 2:
            carcheck();
            break;
            case 0:
            exit(0);
            default:
            printf("您输入的功能编号有误,请重新输入!");
            break;
            }
        }//无限循环
}
void menu()
{
    printf("\n\n\t\t\t══ 神州租车、中国租车领导者 ══\n");
    printf("\t\t\t1:神州专车信息\n");
    printf("\t\t\t2:神州专车结算\n");
    printf("\t\t\t0:退出\n");
}//菜单实现
void carinfor()
{
    char arr[20],brr[20],ch;//车名,人名,判断条件
    for(;;){
    printf("请选择车型:奥迪/东风本田:");
    fflush(stdin);
    gets(arr);
    if(strcmp(arr,"奥迪")!=0&&strcmp(arr,"东风本田")!=0){
        printf("暂时没有您需要的车型\n");
        continue;
        }
    printf("请选择司机:吴亦凡/黄晓明:");
    fflush(stdin);
    gets(brr);
    if(strcmp(brr,"吴亦凡")!=0&&strcmp(brr,"黄晓明")!=0){
        printf("%s暂时没有上线\n",brr);
        continue;
        }
    printf("是否确认提交订单Y/N:");
    ch=getchar();
    if(ch=='Y'){
        printf("\n本次专车出行,所选车型是;%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元\n");
    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("账号金额不足,请及时充值\n");
        }
    }else if(choice=='N'){
    printf("取消支付成功!\n");
    }else{
    printf("输入字符有误\n");    
      }//是否支付
    }else{
    printf("支付方式无效!");
    }//关于支付宝的判断
}//功能2 结束

 

posted @ 2019-07-16 10:47  Timcode  阅读(466)  评论(0编辑  收藏  举报