任务一:用顺序表实现通讯录管理
1、构建如表1所示的顺序表并输出检验,实现表1。
2、增加插入记录的功能并输出检验,实现表2。
3、增加按学号查找的功能并运行验证。
4、增加删除记录的功能并运行验证。
表1
学号 姓名 性别 手机号码 QQ号
2013001 张珊 女 13800001919 34578
表2
2013002 李思 女 13910121978 8796532
2013003 陈琪 女 13789450012 3789123
2013004 王强 男 13634567856 6543783
2013005 赵括 男 13534408976 5679
2013006 刘刚 男 13386543211 98315
注意:用结构化程序设计的方法实现即(其中的)把单一功能设计成一个独立的函数。如构建顺序表设计成一个函数,同样插入、查找、删除、输出也设计成独立的函数。
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define list_size 5
#define list_initcrement 10
//声明顺序表元素的类型
typedef struct{
char xuehao[14];//学号
char name[20]; //姓名
int sex; //性别
char tel[14]; //联系电话
char qq[12]; //QQ号
}ElemType;
typedef struct {
ElemType *elem; //存放一个元素或者说一个节点的基地址
int length;
int listsize;
}SeqList;
//顺序表的初始化
void initSeqlist(SeqList &L){
char flag; //用来标识是否进行输入
int i,n; //标识当前输入的第几个参数;用来标识要初始化参数的个数
L.elem= (ElemType *)malloc(list_size * sizeof(ElemType) );
L.length=0;
L.listsize=list_size;
printf("空表初始化完成初");
printf("下面请是否对空表进行初始化数据Y/N\n");
scanf("%c",&flag);
if(flag=='N'||flag=='n')return;
printf("请输入要初始化的参数个数\n");
scanf("%d",&n);
if(n>L.listsize){
printf("对不起您要输入的参数个数多余我们所初始化的空间了");
return;
}
ElemType *p;
p=L.elem;
for(i=0;i<n;i++){
printf("请输入第%d个数据(学号 姓名 性别(0或1) 联系电话 QQ号):\n",i+1);//每次输入完毕后i+1
scanf("%s%s%d%s%s", p[i].xuehao ,p[i].name , &p[i].sex, p[i].tel,p[i].qq );
L.length+=1;
printf("当前顺序表中参数个数为:");
printf("%d\n",L.length);
}
printf("参数录入完毕\n");
}
//输出顺序表中的元素
int printSeqlist(SeqList &L)
{
if(L.length==0){
printf("您的表还是空表,请先进行初始化操作");
return 0;
}
printf("学号 姓名 性别 联系电话 QQ号\n");
int i;
for(i=0;i<=L.length-1;i++){
printf("%s\t%s",L.elem[i].xuehao,L.elem[i].name);
if(L.elem[i].sex)printf("男");
else printf("女");
printf("\t%s\t%s\n",L.elem[i].tel,L.elem[i].qq) ;
}
printf("当前表中元素个数是:");
printf("%d",L.length);
printf("还剩下%d个位置:\n",L.listsize-L.length);
return 1;
}
//插入数据,向L表中的第i个位置,插入数据元素e
int insertSqelist(SeqList &L,int i,ElemType &e){
if(L.length>=L.listsize){
printf("表满插入失败");
return 0;
}
if(i<1||i>L.length+1){
printf("插入的位置错误");
return 0;
}
ElemType *p,*q; //声明一个节点类型
q=L.elem+i-1; //获取第i个元素的地址
for(p=L.elem+L.length-1;p>=q;p--){//判断条件里面必须要有等于号,不然的话原先第i的值会被丢弃掉且原先的第i+1为空值
*(p+1)=*p;
}
*q=e; //把e的地址赋
L.length++;
return 1;
}
//根据学号查找该学生的信息
int LocateList(SeqList &L,ElemType &e){
int i;
printf("您要查找的元素信息为:\n");
for(i=0;i<=L.length-1;i++){
if(strcmp(L.elem[i].xuehao, e.xuehao)==0){
printf("%s\t%s",L.elem[i].xuehao,L.elem[i].name);
if(L.elem[i].sex)printf(" 男");
else printf("女");
printf("\t%s\t%s\n",L.elem[i].tel,L.elem[i].qq) ;
}
}
return 0;
}
int InsetElemType(SeqList &L,ElemType &e){
printf("请输入要插入的数据(学号 姓名 性别(0或1) 联系电话 QQ号):\n");
scanf("%s%s%d%s%s",e.xuehao,e.name , &e.sex , e.tel ,e.qq );
printf("学号 姓名 性别 联系电话 QQ号\n");
printf("%s\t%s\t",e.xuehao,e.name );
if(e.sex)
printf("男");
else printf("女");
printf("\t%s\t%6s\n", e.tel ,e.qq );
printf("请输入你要在那个位置插入这个节点:");
int i;
scanf("%d",&i);
insertSqelist(L,i,e);
printSeqlist(L);
return 1;
}
//按照学生序号进行删除该元素或者说是记录
int DeleteSeqList(SeqList &L,ElemType &e){
int i;
ElemType *p,*q;
for(i=0;i<L.length-1;i++){
if(strcmp(L.elem[i].xuehao,e.xuehao)==0){
(*p)=L.elem[i];//表示e.xuehao所对应的元素位置
e=*p;
q=L.elem+L.length;//尾元素的位置
for(++p;p<=q;++p){
*(p-1)=*p;
}
--L.length;
//printf("找到了");
}else{
printf("没有该学号\n");
return 0;
}
}
return 0;
}
int main(){
SeqList L; //声明一个顺序表类型;
ElemType e; //声明一个节点类型
int choice;
do{
printf(" 通讯录管理系统\n");
printf("======================================\n");
printf(" 1:退出\n");
printf(" 2:初始化顺序表\n");
printf(" 3:插入\n");
printf(" 4:删除\n");
printf(" 5:查询\n");
printf(" 6:输出\n");
printf("======================================\n");
printf("请选择1-6\n");
scanf("%d",&choice);
while(choice<1||choice>6){
printf("输入错误重新输入");
scanf("%d",&choice);
}
switch(choice){
case 1:exit(1);
case 2:initSeqlist(L);break;//初始化顺序表,通过键入记录的方式
case 3:InsetElemType(L,e);break;
case 4:
printf("请输入要删除记录的学号:\n");
scanf("%s",e.xuehao);
printf("要删除的学号为%s\n",e.xuehao);
DeleteSeqList(L,e);
break;
case 5:
printf("请输入要查询的学号:\n");
scanf("%s",e.xuehao );
printf("要查询的学号为%s\n",e.xuehao);
LocateList(L,e);
break;
case 6:printSeqlist(L);break;
}
}while(choice);
return 0 ;
}
//温馨提示在按学号删除该元素的时候一次只能删除一个,这是因为
//在编写该方法的时候没有考虑一次性多删除,但是可以通过加入While来进行删除。
//因为通过删除(sqeList &L,int i,ElemType &e)方式通过传入元素序号删除比较容易,本文中是通过元素的列或者叫项来进行删除的。
在比较元素项的时候通过比较字符串的方式进行删除,切记不能用==
这是因为字符串比较是不能通过简单的==来进行比较,比较的不是值
而是字符串的地址。