单位员工通讯录管理系(线性表的应用)
1.问题描述
[题目描述]
为某个单位建立一个员工通讯录管理系统,可以方便查询每一个员工的手机号、及电子邮箱。其功能包括通讯录链表的建立、员工通讯信息的查询、修改、插入与删除、以及整个通讯录表的输出。
操作分为查询(query)、修改(modify)、添加(add)、删除(del)、打印(print)
1. 查询:输入员工姓名,输出员工信息,若员工不存在,输出“NOT FOUND!”
2. 修改:输入员工姓名、要修改的属性、修改信息。姓名为name、电话为tel、邮箱为email。
3. 添加:输入员工编号、姓名、电话号码、邮箱。
4. 删除:输入员工姓名,将其从通讯录中删除。
5. 打印:输出通讯录。
[输入]
第一行是一个整数n(1<=n<=100),表示通讯录原有n个人。接下来n行是员工信息,每行有编号、姓名、电话号码、邮箱四个员工属性。
接下来输入一个整数m(1<=m<=100),表示有m次操作。接下来是m行操作,每行为一次操作,操作如题意所示。
数据保证编号、姓名不重复;编号小于200且升序给出,名字只由小写字母组成,电话只由数字组成,邮箱只由数字、小写字母、“@”、“.”组成;名字、电话、邮箱字符串长度都不超过20。
[输出]
对于每个query和print,输出查询或打印结果。
[样例输入]
2
1 aaa 13579246811 aaa@gmail.com
2 csl 13579246833 cls@gmail.com
9
del aaa
query aaa
query csl
modify csl email clsnb@gmail.com
query csl
add 3 cnz 01234567890 cnznb@gmail.com
modify cnz name cnznb
modify cnznb tel 13579246822
[样例输出]
2 csl 13579246833 cls@gmail.com
2 csl 13579246833 clsnb@gmail.com
2 csl 13579246833 clsnb@gmail.com
3 cnznb 13579246822 cnznb@gmail.com
[提示]
样例中,
del aaa 表示删除aaa的信息
query aaa 查询aaa的信息,不存在,输出“NOT FOUND!”
query csl 表示查询csl的信息,输出“2 csl 13579246833 cls@gmail.com”
modify csl email clsnb@gmail.com 表示修改csl的邮箱为“clsnb@gmail.com”
query csl 表示查询csl的信息,输出“2 csl 13579246833 clsnb@gmail.com”
add 3 cnz 01234567890 cnznb@gmail.com 添加一条员工信息
modify cnz name cnznb 修改cnz的name为cnznb
modify cnznb tel 13579246822 修改cnz的tel为13579246822
print 按编号顺序打印通讯录
2.需求分析
可以采用单链表的存储结构,如可定义如下的存储结构:
typedef struct { /*员工通讯信息的结构类型定义*/
char num[5]; /*员工编号*/
char name[10]; /*员工姓名*/
char call[15]; /*手机号码*/
char mail[25]; /*邮箱*/
}DataType;
typedef struct LNode{
DataType data; //结点的数据域
LNode *next; //结点的指针域
}*LinkList,LNode; //LinkList为指向结构体LNode的指针类型
3.算法设计
1. CreatList_R(LinkList &L,int n)——尾插法建立空链表
2. listlength(LinkList L)——遍历求单链表的长度
3. GetElem(LinkList L)——根据编号遍历链表查询员工信息
4. ListInsert(LinkList &L,int i)——在表头节点前插入节点
5. ListDelete(LinkList &L)——遍历链表找到待删节点前驱后进行删除操作
6. show(LinkList L)——显示链表所有元素
7. xiugai(LinkList L)——对链表中的数据进行修改
4.调试分析
采用链式存储结构,插入和删除速度快,只需改变指针指向即可,但是查找速度慢,查找时需要循环链表访问。
5.实验结果
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int Boolean;
typedef int ElemType;
typedef struct { /*员工通讯信息的结构类型定义*/
char num[5]; /*员工编号*/
char name[10]; /*员工姓名*/
char call[15]; /*手机号码*/
char mail[25]; /*邮箱*/
}DataType;
typedef struct LNode{
DataType data; //结点的数据域
LNode *next; //结点的指针域
}*LinkList,LNode; //LinkList为指向结构体LNode的指针类型
void CreatList_R(LinkList &L,int n)//尾插法建立空链表
{//正位序输入n个元素的值,建立带头结点的单链表L
LinkList p,r;
L=new LNode;
L->next=NULL; //先建立一个带头结点的空链表
r=L; //尾指针r指向头结点
for(int i=0;i<n;i++)
{
p=new LNode; //生成新结点
cin>>p->data.num>>p->data.name>>p->data.call>>p->data.mail; //输入元素值赋给新结点*p的数值域
p->next=NULL;r->next=p; //将新结点*p插入尾结点*r之后
r=p; //r指向新的尾结点*p
}
}
int listlength(LinkList L)
{
int count = 0;
LinkList p = L->next;
while (p)
{
count++;
p = p->next;
}
return count;
}
void GetElem(LinkList L)//查询
{
LinkList p;
p=L->next; //初始化,p指向首元结点
char s[25];
cin>>s;
while (p)
{
if (!strcmp(s,p->data.name))
break;
p = p->next;
}
if (!p){ cout << "NOT FOUND!"<<endl; }
else{
cout<<p->data.num<<" "<<p->data.name<<" "<<p->data.call<<" "<<p->data.mail<<endl;
}
}
Status ListInsert(LinkList &L,int i)//插入
{//在带头结点的单链表L中第i个 位置插入值为e的新结点
LinkList p,s;
p=L;int j=0;
while(p&&(j<i-1))
{p=p->next;j++; } //查找第i-1个结点,p指向该结点
if(!p||j>i-1) return ERROR; //i>n+1或者i<1
s=new LNode; //生成新结点*s
cin>>s->data.num >>s->data.name>>s->data.call>>s->data.mail; //将结点*s的数据域置为e
s->next=p->next; //将结点*s的指针域指向结点ai
p->next=s; //将结点*p的指针域指向结点*s
}
Status ListDelete(LinkList &L)//删除
{//在带头结点的单链表L中,删除第i个元素
int i = 1, j;
LinkList p = L->next;
LinkList q=L;//q的前一个节点位置
char s[25];
cin>>s;
while (p)
{
if (!strcmp(s, p->data.name))
break;
p = p->next;
i++;
}
for (j = 1; j <= i - 1; j++)
q = q->next;
q->next = p->next;
delete p;
return OK;
}
void show(LinkList L)//显示链表所有元素
{
LinkList p;
p=L->next ; //初始化,p指向首元结点
while(p)
{
cout<<p->data.num<<" "<<p->data.name<<" "<<p->data.call<<" "<<p->data.mail<<endl; //输出p的数据域
p=p->next; //p指向下一个结点
}
}
void xiugai(LinkList L)//对链表中的数据进行修改
{
LinkList p = L->next;
char s1[25],s2[25],m[25],k[25];
cin >> s1>>s2;
// while (p)
// {
// if (!strcmp(s1, p->data.name))
// break;
// p = p->next;
// }
if(!strcmp(s2,"name")) {
while (p)
{
if (!strcmp(s1, p->data.name))
break;
p = p->next;
}
cin>>p->data.name;
}
if(!strcmp(s2,"tel")){
while (p)
{
if (!strcmp(s1, p->data.name))
break;
p = p->next;
}cin>>p->data.call;
}
if(!strcmp(s2,"email")) {
while (p)
{
if (!strcmp(s1, p->data.name))
break;
p = p->next;
}cin>>p->data.mail;
}
}
int main()
{
int n,m,i;
char s[25];
LinkList L;
cin>>n;
CreatList_R(L,n);
cin>>m;
for(i=0;i<m;i++)
{
cin>>s;
if(!strcmp(s,"query")) GetElem(L);
if(!strcmp(s,"modify")) xiugai(L);
if(!strcmp(s,"add")) {
int n=listlength(L);
ListInsert(L,n+1);
}
if(!strcmp(s,"del")) ListDelete(L);
if(!strcmp(s,"print")) show(L);
}
return 0;
}