一、 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. 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 结束