数据结构课程设计---通讯录管理系统(C++)
通讯录管理系统:通讯录是用来记载和查询联系人通讯信息的工具。电子通讯录已成为手机、电子词典等电子设备中不可缺少的工具软件。请设计一个能够满足这种需求的软件。基本功能涵盖:输入、显示、查找、插入、删除、保存、读入、排序、修改、退出。...
目录
一、实验题目
通讯录管理系统:通讯录是用来记载和查询联系人通讯信息的工具。电子通讯录已成为手机、电子词典等电子设备中不可缺少的工具软件。请设计一个能够满足这种需求的软件。
基本功能涵盖:输入、显示、查找、插入、删除、保存、读入、排序、修改、退出。
二、数据结构设计
(一)存储结构设计
通讯录中的记录通常按照记载顺序先后有序,因此逻辑结构选用线性结构。考虑到本设计中经常需要进行插入和删除操作,于是物理结构采用链式结构。综上所述,本设计采用链表存储通讯记录。
(二)结点结构设计
本设计中一条记录中涉及着较多的数据项,因此需要单独对数据域进行定义。数据域ElemType中共存储七个数据项:序号、姓名、性别、年龄、电话、地址以及分组,根据不同的数据项对其赋予合适的变量类型。LinkList指针域为一个next指针。
1.通讯录数据域
typedef struct
{
int num;
string name;
string sex;
int age;
string telephone;
string address;
string relation;
}ElemType;
2.链表
typedef struct Node
{
ElemType data;
struct Node* next;
}Node, * LinkList;
三、算法设计
(一)函数设计
一共涉及十三个函数,通过这十三个函数之间的相互调用,实现通讯录管理系统的各种功能。
1.Read()函数
用于将文本中的记录读取到程序中,便于进行后续的操作。支持一次性读取大量的记录;
//读取功能
void Read(LinkList& L)
{
Node* p = L;
ifstream infile("E://book.txt", ios::in);
int len = 0;
infile >> len;
ElemType tem;
while(len--)
{
infile>>tem.num>>tem.name>>tem.sex>>tem.age>>tem.telephone>>tem.address>>tem.relation;
Node* t = new Node;
t->data = tem;
t->next = NULL;
p->next = t;
p = p->next;
}
infile.close();
}
2.Save()函数
输出保存的记录的个数以及将所有记录都保存到文本中;
//存储功能
void Save(LinkList& L)
{
Node* t = L, * cnt = L;
ofstream outfile("E://contact.txt", ios::out);
int len = 0;
while(cnt->next)
{
len++;
cnt = cnt->next;
}
outfile<<len<<endl;
while(t)
{
if(t != L)
outfile << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
t = t->next;
}
outfile.close();
}
3.Init_LinkList()函数
初始化链表,设置头结点,并将指针指向NULL;
//初始化链表
void Init_LinkList(LinkList& L)
{
L = new Node;
L->next = NULL;
}
4.Create_LinkList()函数
首先清屏,然后新建一个结点,输入新添加的信息,设置一个对电话号码的有效性的简单验证,接着将该结点用尾插法插入链表,最后判断是否继续添加联系人;
//添加功能
void Create_LinkList(LinkList& L)
{
system("cls");
cout << "\t\t\t添加联系人功能" << endl;
Node* t = L;
int i = 1, flag = 1;
while(t->next)
{
i++;
t = t->next;
}
while (flag)
{
Node* p = new Node;
cout<< "\t\t\t输入姓名:";
cin>> p->data.name;
cout<< "\t\t\t输入性别:";
cin>> p->data.sex;
cout<< "\t\t\t输入年龄:";
cin>>p->data.age;
cout<< "\t\t\t输入电话:";
int m=1;
while(m)
{
cin>>p->data.telephone;
int n=p->data.telephone.length();
if(n!=11)
{
cout<< "\t\t\t输入格式错误,请重新输入:";
m=1;
}
else
{
for(int j=0;j<n;j++)
{
if(!(p->data.telephone[j]>='0' && p->data.telephone[j]<='9'))
{
cout<< "\t\t\t输入格式错误,请重新输入:";
m=1;
break;
}
}
m=0;
}
}
cout << "\t\t\t输入地址:";
cin >> p->data.address;
cout << "\t\t\t输入分组:";
cin >> p->data.relation;
p->data.num = i++;
p->next = NULL;
t->next = p;
t = t->next;
Save(L);
cout << "\t\t\t成功添加一次,选择是否继续本功能(1 是 0 否)" << endl;
cout << "\t\t\t请选择【0-1】:";
cin >> flag;
}
}
5.Delete_LinkList()函数
首先设置两种删除方式,一种是按编号删除,另一种是按姓名删除。考虑到有效性,将错误输入格式进行重新输入。接着是寻找删除结点进行删除;
//删除功能
void Delete_LinkList(LinkList& L)
{
system("cls");
cout << "\t\t\t删除联系人功能" << endl;
int sel = 0;
Node* p = L, * t = NULL;
ElemType tem;
cout<< "\t\t\t1.按编号删除" << endl;
cout<< "\t\t\t2.按姓名删除" << endl;
cout<< "\t\t\t3.返回主菜单" << endl;
cout<< "\t\t\t请选择【1-3】:";
cin>> sel;
while(sel < 1 || sel>3)
{
cout<< "\t\t\t输入格式错误,请重新输入:";
cin>> sel;
}
if(sel == 1)
{
int flag = 0;
cout<< "\t\t\t请输入删除联系人的编号:";
cin>> tem.num;
while(p->next)
{
t = p->next;
if(t->data.num == tem.num)
{
cout<< "\t\t\t待删除联系人信息如下:" << endl;
cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
flag = 1;
break;
}
p = p->next;
}
if(flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
else
{
cout << "\t\t\t确认删除?(1 是 0 否)" << endl;
cout << "\t\t\t请选择【0-1】:";
cin >> sel;
while (sel < 0 || sel>1)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 0);
else
{
if (sel == 1)
{
p->next = t->next;
delete t;
cout << "\t\t\t删除成功!" << endl;
Save(L);
}
}
}
cout << "\n\t\t\t";
system("pause");
Delete_LinkList(L);
}
else if(sel == 2)
{
int flag = 0;
cout << "\t\t\t请输入待删除联系人的姓名:";
cin >> tem.name;
while (p->next)
{
t = p->next;
if (t->data.name == tem.name)
{
cout<< "\t\t\t待删除联系人信息如下:" << endl;
cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
flag = 1;
break;
}
p = p->next;
}
if (flag == 0)
cout << "\t\t\t该通讯录中无此人!" << endl;
else
{
cout << "\t\t\t确认删除?(1 是 0 否)" << endl;
cout << "\t\t\t请选择【0-1】:";
cin >> sel;
while (sel < 0 || sel>1)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 0);
else if (sel == 1)
{
p->next = t->next;
delete t;
cout << "\t\t\t删除成功!" << endl;
Save(L);
}
}
cout << "\n\t\t\t";
system("pause");
Delete_LinkList(L);
}
else if (sel == 3) return;
}
6.Query_LinkList()函数
设置两种查询方式,一种是按编号查询,另一种是按姓名查;
//查询功能
void Query_LinkList(const LinkList& L)
{
system("cls");
cout << "\t\t\t查询联系人功能" << endl;
int sel = 0;
Node* t = L;
ElemType tem;
cout << "\t\t\t1.按编号查询" << endl;
cout << "\t\t\t2.按姓名查询" << endl;
cout << "\t\t\t3.返回主菜单" << endl;
cout << "\t\t\t请选择【1-3】:";
cin >> sel;
while (sel < 1 || sel>3)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 1)
{
int flag = 0;
cout << "\t\t\t请输入待查询联系人的编号:";
cin >> tem.num;
while (t->next)
{
t = t->next;
if (t->data.num == tem.num)
{
cout << "\t\t\t待查询联系人信息如下:" << endl;
cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
flag = 1;
break;
}
}
if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
cout << "\n\t\t\t";
system("pause");
Query_LinkList(L);
}
else if (sel == 2)
{
int flag = 0;
cout << "\t\t\t请输入待查询联系人的姓名:";
cin >> tem.name;
while (t->next)
{
t = t->next;
if (t->data.name == tem.name)
{
cout << "\t\t\t待查询联系人信息如下:" << endl;
cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
flag = 1;
break;
}
}
if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
cout << "\n\t\t\t";
system("pause");
Query_LinkList(L);
}
else if (sel == 3)
{
return;
}
}
7.Modify_LinkList()函数
设置两种修改方式,一种是按编号修改,另一种是按姓名修改。找到位置后对其进行重新输入,修改其数据域;
//修改功能
void Modify_LinkList(LinkList& L)
{
system("cls");
cout << "\t\t\t修改联系人功能" << endl;
int sel = 0;
Node* t = L;
ElemType tem;
cout << "\t\t\t1.按编号修改" << endl;
cout << "\t\t\t2.按姓名修改" << endl;
cout << "\t\t\t3.返回主菜单" << endl;
cout << "\t\t\t请选择【1-3】:";
cin >> sel;
while (sel < 1 || sel>3)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 1)
{
int flag = 0;
cout << "\t\t\t请输入待修改联系人的编号:";
cin >> tem.num;
while (t->next)
{
t = t->next;
if (t->data.num == tem.num)
{
cout << "\t\t\t待修改联系人信息如下:" << endl;
cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
flag = 1;
break;
}
}
if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
else
{
ElemType tem;
cout << "\t\t\t输入修改后的联系人信息:" << endl;
cout << "\t\t\t输入姓名:";
cin >> tem.name;
cout << "\t\t\t输入性别:";
cin >> tem.sex;
cout << "\t\t\t输入年龄:";
cin >> tem.age;
cout << "\t\t\t输入电话:";
int m=1;
while(m)
{
cin>>tem.telephone;
int n=tem.telephone.length();
if(n!=11)
{
cout<< "\t\t\t输入格式错误,请重新输入:";
m=1;
}
else
{
for(int j=0;j<n;j++)
{
if(!(tem.telephone[j]>='0' && tem.telephone[j]<='9'))
{
cout<< "\t\t\t输入格式错误,请重新输入:";
m=1;
break;
}
}
m=0;
}
}
cout << "\t\t\t输入地址:";
cin >> tem.address;
cout << "\t\t\t输入分组:";
cin >> tem.relation;
tem.num = t->data.num;
cout << "\t\t\t确认修改?(1 是 0 否)" << endl;
cout << "\t\t\t请选择【0-1】:";
cin >> sel;
while (sel < 0 || sel>1)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 0);
else if (sel == 1)
{
t->data = tem;
cout << "\t\t\t修改成功!" << endl;
Save(L);
}
}
cout << "\n\t\t\t";
system("pause");
Modify_LinkList(L);
}
else if (sel == 2)
{
int flag = 0;
cout << "\t\t\t请输入待修改联系人的姓名:";
cin >> tem.name;
while (t->next)
{
t = t->next;
if (t->data.name == tem.name)
{
cout << "\t\t\t待修改联系人信息如下:" << endl;
cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
flag = 1;
break;
}
}
if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
else
{
ElemType tem;
cout << "\t\t\t输入修改后的联系人信息:" << endl;
cout << "\t\t\t输入姓名:";
cin >> tem.name;
cout << "\t\t\t输入性别:";
cin >> tem.sex;
cout << "\t\t\t输入年龄:";
cin >> tem.age;
cout << "\t\t\t输入电话:";
int m=1;
while(m)
{
cin>>tem.telephone;
int n=tem.telephone.length();
if(n!=11)
{
cout<< "\t\t\t输入格式错误,请重新输入:";
m=1;
}
else
{
for(int j=0;j<n;j++)
{
if(!(tem.telephone[j]>='0' && tem.telephone[j]<='9'))
{
cout<< "\t\t\t输入格式错误,请重新输入:";
m=1;
break;
}
}
m=0;
}
}
cout << "\t\t\t输入地址:";
cin >> tem.address;
cout << "\t\t\t输入分组:";
cin >> tem.relation;
tem.num = t->data.num;
cout << "\t\t\t确认修改?(1 是 0 否)" << endl;
cout << "\t\t\t请选择【0-1】:";
cin >> sel;
while (sel < 0 || sel>1)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 0);
else if (sel == 1)
{
t->data = tem;
cout << "\t\t\t修改成功!" << endl;
Save(L);
}
}
cout << "\n\t\t\t";
system("pause");
Delete_LinkList(L);
}
else if (sel == 3) return;
}
8.Print_LinkList()函数
从首元结点开始对数据域进行输出显示;
//显示功能
void Print_LinkList(const LinkList& L)
{
system("cls");
cout << "\t\t\t显示功能" << endl;
Node* t = L->next;
cout << "\t\t\t序号\t" << "姓名\t"<< "性别\t"<< "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
while (t)
{
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
t = t->next;
}
cout << "\t\t\t";
system("pause");
}
9.Compare1/2/3/4()函数
是排序中sort()函数的第三个参数,为#include<algorithm>下的自定义排序;
//排序中sort函数第三个参数
bool compare1(const ElemType& t1, const ElemType& t2)
{
return t1.num < t2.num;
}
bool compare2(const ElemType& t1, const ElemType& t2)
{
return t1.name < t2.name;
}
bool compare3(const ElemType& t1, const ElemType& t2)
{
return t1.age < t2.age;
}
bool compare4(const ElemType& t1, const ElemType& t2)
{
return t1.relation < t2.relation;
}
10.Sort_LinkList()函数
设置了四种排序方式,分别是按编号排序、按姓名排序、按年龄排序、按分组排序;
//排序功能
void Sort_LinkList(LinkList& L)
{
system("cls");
cout << "\t\t\t排序功能" << endl;
Node* p = L;
cout << "\t\t\t1.按编号排序" << endl;
cout << "\t\t\t2.按姓名排序" << endl;
cout << "\t\t\t3.按年龄排序" << endl;
cout << "\t\t\t4.按分组排序" << endl;
cout << "\t\t\t5.返回主菜单" << endl;
cout << "\t\t\t请选择【1-5】:";
int cnt = 0, i = 0;
int sel;
cin>>sel;
while (sel < 1 || sel > 5)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
while (p->next)
{
p = p->next;
cnt++;
}
ElemType* arr = new ElemType[cnt];
p = L;
while (p->next)
{
p = p->next;
arr[i++] = p->data;
}
if(sel==1)
{
sort(arr, arr + cnt, compare1);
}
else if(sel==2)
{
sort(arr, arr + cnt, compare2);
}
else if(sel==3)
{
sort(arr, arr + cnt, compare3);
}
else if(sel==4)
{
sort(arr, arr + cnt, compare4);
}
else if(sel==5) return;
p = L, i = 0;
while (p->next)
{
p = p->next;
p->data = arr[i++];
p->data.num = i;
}
cout << "\t\t\t对通讯录进行排序并整理如下:" << endl;
Node* t = L->next;
cout << "\t\t\t序号\t" << "姓名\t" <<"性别\t" <<"年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
while (t)
{
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
t = t->next;
}
Save(L);
cout << "\n\t\t\t";
system("pause");
Sort_LinkList(L);
}
11.Clear_LinkList()函数
清空链表,但是头结点还存在;
//清空功能
void Clear_LinkList(LinkList& L)
{
int sel = 0;
system("cls");
cout << "\t\t\t清空功能" << endl;
cout << "\t\t\t1 确认清空通讯录" << endl;
cout << "\t\t\t2 返回主菜单" << endl;
cout << "\t\t\t请选择【1-2】:";
cin >> sel;
while (sel < 1 || sel>2)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 1)
{
Node* head = L;
if (head == NULL)
{
return;
}
Node* curNode = head->next;
while (curNode != NULL)
{
Node* nextNode = curNode->next;
free(curNode);
curNode = nextNode;
}
head->next = NULL;
Save(L);
cout << "\n\t\t\t";
system("pause");
}
else if (sel == 2) return;
}
12.Menu()函数
菜单功能,对本设计的共八种功能进行调用;
//菜单功能
void menu(LinkList& L)
{
char sel;
system("cls");
cout << "\t\t\t通讯录管理系统" << endl;
cout << "\t\t\t你可以进行以下操作:" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 1.添加联系人 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 2.删除联系人 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 3.修改联系人 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 4.查询联系人 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 5.通讯录显示 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 6.通讯录排序 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 7.通讯录清空 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 0.退出 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t请选择【0-7】:";
cin >> sel;
while (sel < '0' || sel>'7')
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
switch (sel)
{
case '1':
Create_LinkList(L);
menu(L);
break;
case '2':
Delete_LinkList(L);
menu(L);
break;
case '3':
Modify_LinkList(L);
menu(L);
break;
case '4':
Query_LinkList(L);
menu(L);
break;
case '5':
Print_LinkList(L);
menu(L);
break;
case '6':
Sort_LinkList(L);
menu(L);
break;
case '7':
Clear_LinkList(L);
menu(L);
break;
case '0':
exit(0);
default:
menu(L);
}
}
13.Main()函数
主函数,对各个函数调用实现通讯录管理系统的各种功能。
//主函数
int main()
{
system("color 71");
LinkList L;
Init_LinkList(L);
Read(L);
menu(L);
return 0;
}
(二)算法描述
算法思想:
通讯录管理系统要实现输入、显示、查找、插入、删除、保存、读入、排序、修改、退出的基本功能。因此总体考虑下,由一个主函数和若干个函数构成。主函数主要负责对各个函数的联合调用,实现通讯录管理系统的各个功能,其他函数则对应着不同的功能,将一个功能封装成一个函数,对应实施。
读入功能:设置指针p从头结点开始,先将文本book.txt中的第一行内容导入。再通过len控制导入次数,实现将文本中的数据逐个读入,中间变量指针tem、t。最后关闭文本。
保存功能:将指针t指向链表L的头结点,打开待存入的文本,通过指针cnt以及int变量len从首元结点扫描到尾结点,计算出链表的长度,并存入文本。在while的循环下从首元结点开始到尾结点,逐个结点地将数据域保存在文本中。
初始化链表:建立头结点,将头结点的指针指向NULL。
插入功能:首先利用system("cls")进行清屏,接着开始利用t指针和i变量,统计出当前的链表长度。设置标志位flag控制添加的次数,将姓名、性别、年龄等信息逐个输入。在当前输入中设置了一个输入数据有效性检验,对输入的电话号码进行简单的判断,确认其有效性,若格式存在问题,则重新输入。将该结点尾插法插入链表中,并进行下一次的判断,继续添加还是退出。
删除功能:设置两种删除的方式,一种是按照编号删除,另一种是按照姓名删除。对输入的选择进行有效性检验,若不满足则重新输入。当sel等于1的时候,对链表进行遍历操作,若找到了与编号相等的数据,则现将其输出。利用flag标志位判断是否找到,若找到,则再次确认是否确定删除,通过将p指针指向t指针的下一个结点,先将t结点从链表中去除,再用delete删除。第二种方法与第一种方法思路基本相似,只是在编号的地方改成了姓名。
查找功能:查找功能与删除功能大致相同,不同点在于只需找到即可,不需要再执行删除功能。
修改功能:修改功能与删除功能大致相同,不同点在于在找到之后,将删除功能改为了修改。在数据域的输入中,设置了有效性的检验,对电话号码的有效性进行了简单的检验,若格式错误,需要重新输入操作。且设置了一个sel位,判断是否决定修改,更加贴合现实。
显示功能:直接从首元结点开始遍历,将每个结点的数据域输出。
排序功能:设置四种方式的排序方法,一种是按编号排序、一种是按姓名排序、一种是按年龄排序还有一种是按分组排序。设置指针p和int类型变量cnt,统计出链表的长度。设置数据域类型数组,得到排序的起始位置。利用自定义sort()进行排序,根据sel选择不同的排序要求。再将排序后的数组重新装回链表。最后进行输出显示排序后的结果。
清空功能:当sel等于1时,实现清空功能。首先判断通讯录中是否存在记录,接着将curNode结点指向首元结点,并将其的下一个结点赋给nextNode,用free()将curNode结点销毁。循环执行,直至链表成为空链表。
菜单功能:将几种功能显示出来,并标上编号,以供选择。通过“-|”修饰菜单,使其起美化效果。对sel的输入进行有效性检验,若输入不符合规范,进行重新输入。通过switch()对选择的功能函数进行调用。
主函数:为起修饰性作用,system(“color 71”)用来美化字体和背景。首先创建链表,然后将文本中的数据读入系统,接着实现通讯录的管理系统的各种功能。
以上是各个功能模块的实现思路,将其一一编写出,即可最终实现通讯管理系统。
四、完整代码
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<fstream>
using namespace std;
//通讯录数据元素
typedef struct
{
int num;
string name;
string sex;
int age;
string telephone;
string address;
string relation;
}ElemType;
//链表
typedef struct Node
{
ElemType data;
struct Node* next;
}Node, * LinkList;
//读取功能
void Read(LinkList& L)
{
Node* p = L;
ifstream infile("E://book.txt", ios::in);
int len = 0;
infile >> len;
ElemType tem;
while(len--)
{
infile>>tem.num>>tem.name>>tem.sex>>tem.age>>tem.telephone>>tem.address>>tem.relation;
Node* t = new Node;
t->data = tem;
t->next = NULL;
p->next = t;
p = p->next;
}
infile.close();
}
//存储功能
void Save(LinkList& L)
{
Node* t = L, * cnt = L;
ofstream outfile("E://contact.txt", ios::out);
int len = 0;
while(cnt->next)
{
len++;
cnt = cnt->next;
}
outfile<<len<<endl;
while(t)
{
if(t != L)
outfile << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
t = t->next;
}
outfile.close();
}
//初始化链表
void Init_LinkList(LinkList& L)
{
L = new Node;
L->next = NULL;
}
//添加功能
void Create_LinkList(LinkList& L)
{
system("cls");
cout << "\t\t\t添加联系人功能" << endl;
Node* t = L;
int i = 1, flag = 1;
while(t->next)
{
i++;
t = t->next;
}
while (flag)
{
Node* p = new Node;
cout<< "\t\t\t输入姓名:";
cin>> p->data.name;
cout<< "\t\t\t输入性别:";
cin>> p->data.sex;
cout<< "\t\t\t输入年龄:";
cin>>p->data.age;
cout<< "\t\t\t输入电话:";
int m=1;
while(m)
{
cin>>p->data.telephone;
int n=p->data.telephone.length();
if(n!=11)
{
cout<< "\t\t\t输入格式错误,请重新输入:";
m=1;
}
else
{
for(int j=0;j<n;j++)
{
if(!(p->data.telephone[j]>='0' && p->data.telephone[j]<='9'))
{
cout<< "\t\t\t输入格式错误,请重新输入:";
m=1;
break;
}
}
m=0;
}
}
cout << "\t\t\t输入地址:";
cin >> p->data.address;
cout << "\t\t\t输入分组:";
cin >> p->data.relation;
p->data.num = i++;
p->next = NULL;
t->next = p;
t = t->next;
Save(L);
cout << "\t\t\t成功添加一次,选择是否继续本功能(1 是 0 否)" << endl;
cout << "\t\t\t请选择【0-1】:";
cin >> flag;
}
}
//删除功能
void Delete_LinkList(LinkList& L)
{
system("cls");
cout << "\t\t\t删除联系人功能" << endl;
int sel = 0;
Node* p = L, * t = NULL;
ElemType tem;
cout<< "\t\t\t1.按编号删除" << endl;
cout<< "\t\t\t2.按姓名删除" << endl;
cout<< "\t\t\t3.返回主菜单" << endl;
cout<< "\t\t\t请选择【1-3】:";
cin>> sel;
while(sel < 1 || sel>3)
{
cout<< "\t\t\t输入格式错误,请重新输入:";
cin>> sel;
}
if(sel == 1)
{
int flag = 0;
cout<< "\t\t\t请输入删除联系人的编号:";
cin>> tem.num;
while(p->next)
{
t = p->next;
if(t->data.num == tem.num)
{
cout<< "\t\t\t待删除联系人信息如下:" << endl;
cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
flag = 1;
break;
}
p = p->next;
}
if(flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
else
{
cout << "\t\t\t确认删除?(1 是 0 否)" << endl;
cout << "\t\t\t请选择【0-1】:";
cin >> sel;
while (sel < 0 || sel>1)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 0);
else
{
if (sel == 1)
{
p->next = t->next;
delete t;
cout << "\t\t\t删除成功!" << endl;
Save(L);
}
}
}
cout << "\n\t\t\t";
system("pause");
Delete_LinkList(L);
}
else if(sel == 2)
{
int flag = 0;
cout << "\t\t\t请输入待删除联系人的姓名:";
cin >> tem.name;
while (p->next)
{
t = p->next;
if (t->data.name == tem.name)
{
cout<< "\t\t\t待删除联系人信息如下:" << endl;
cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
flag = 1;
break;
}
p = p->next;
}
if (flag == 0)
cout << "\t\t\t该通讯录中无此人!" << endl;
else
{
cout << "\t\t\t确认删除?(1 是 0 否)" << endl;
cout << "\t\t\t请选择【0-1】:";
cin >> sel;
while (sel < 0 || sel>1)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 0);
else if (sel == 1)
{
p->next = t->next;
delete t;
cout << "\t\t\t删除成功!" << endl;
Save(L);
}
}
cout << "\n\t\t\t";
system("pause");
Delete_LinkList(L);
}
else if (sel == 3) return;
}
//查询功能
void Query_LinkList(const LinkList& L)
{
system("cls");
cout << "\t\t\t查询联系人功能" << endl;
int sel = 0;
Node* t = L;
ElemType tem;
cout << "\t\t\t1.按编号查询" << endl;
cout << "\t\t\t2.按姓名查询" << endl;
cout << "\t\t\t3.返回主菜单" << endl;
cout << "\t\t\t请选择【1-3】:";
cin >> sel;
while (sel < 1 || sel>3)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 1)
{
int flag = 0;
cout << "\t\t\t请输入待查询联系人的编号:";
cin >> tem.num;
while (t->next)
{
t = t->next;
if (t->data.num == tem.num)
{
cout << "\t\t\t待查询联系人信息如下:" << endl;
cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
flag = 1;
break;
}
}
if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
cout << "\n\t\t\t";
system("pause");
Query_LinkList(L);
}
else if (sel == 2)
{
int flag = 0;
cout << "\t\t\t请输入待查询联系人的姓名:";
cin >> tem.name;
while (t->next)
{
t = t->next;
if (t->data.name == tem.name)
{
cout << "\t\t\t待查询联系人信息如下:" << endl;
cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
flag = 1;
break;
}
}
if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
cout << "\n\t\t\t";
system("pause");
Query_LinkList(L);
}
else if (sel == 3)
{
return;
}
}
//修改功能
void Modify_LinkList(LinkList& L)
{
system("cls");
cout << "\t\t\t修改联系人功能" << endl;
int sel = 0;
Node* t = L;
ElemType tem;
cout << "\t\t\t1.按编号修改" << endl;
cout << "\t\t\t2.按姓名修改" << endl;
cout << "\t\t\t3.返回主菜单" << endl;
cout << "\t\t\t请选择【1-3】:";
cin >> sel;
while (sel < 1 || sel>3)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 1)
{
int flag = 0;
cout << "\t\t\t请输入待修改联系人的编号:";
cin >> tem.num;
while (t->next)
{
t = t->next;
if (t->data.num == tem.num)
{
cout << "\t\t\t待修改联系人信息如下:" << endl;
cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
flag = 1;
break;
}
}
if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
else
{
ElemType tem;
cout << "\t\t\t输入修改后的联系人信息:" << endl;
cout << "\t\t\t输入姓名:";
cin >> tem.name;
cout << "\t\t\t输入性别:";
cin >> tem.sex;
cout << "\t\t\t输入年龄:";
cin >> tem.age;
cout << "\t\t\t输入电话:";
int m=1;
while(m)
{
cin>>tem.telephone;
int n=tem.telephone.length();
if(n!=11)
{
cout<< "\t\t\t输入格式错误,请重新输入:";
m=1;
}
else
{
for(int j=0;j<n;j++)
{
if(!(tem.telephone[j]>='0' && tem.telephone[j]<='9'))
{
cout<< "\t\t\t输入格式错误,请重新输入:";
m=1;
break;
}
}
m=0;
}
}
cout << "\t\t\t输入地址:";
cin >> tem.address;
cout << "\t\t\t输入分组:";
cin >> tem.relation;
tem.num = t->data.num;
cout << "\t\t\t确认修改?(1 是 0 否)" << endl;
cout << "\t\t\t请选择【0-1】:";
cin >> sel;
while (sel < 0 || sel>1)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 0);
else if (sel == 1)
{
t->data = tem;
cout << "\t\t\t修改成功!" << endl;
Save(L);
}
}
cout << "\n\t\t\t";
system("pause");
Modify_LinkList(L);
}
else if (sel == 2)
{
int flag = 0;
cout << "\t\t\t请输入待修改联系人的姓名:";
cin >> tem.name;
while (t->next)
{
t = t->next;
if (t->data.name == tem.name)
{
cout << "\t\t\t待修改联系人信息如下:" << endl;
cout<< "\t\t\t编号\t" << "姓名\t" << "性别\t" << "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
flag = 1;
break;
}
}
if (flag == 0) cout << "\t\t\t该通讯录中无此人!" << endl;
else
{
ElemType tem;
cout << "\t\t\t输入修改后的联系人信息:" << endl;
cout << "\t\t\t输入姓名:";
cin >> tem.name;
cout << "\t\t\t输入性别:";
cin >> tem.sex;
cout << "\t\t\t输入年龄:";
cin >> tem.age;
cout << "\t\t\t输入电话:";
int m=1;
while(m)
{
cin>>tem.telephone;
int n=tem.telephone.length();
if(n!=11)
{
cout<< "\t\t\t输入格式错误,请重新输入:";
m=1;
}
else
{
for(int j=0;j<n;j++)
{
if(!(tem.telephone[j]>='0' && tem.telephone[j]<='9'))
{
cout<< "\t\t\t输入格式错误,请重新输入:";
m=1;
break;
}
}
m=0;
}
}
cout << "\t\t\t输入地址:";
cin >> tem.address;
cout << "\t\t\t输入分组:";
cin >> tem.relation;
tem.num = t->data.num;
cout << "\t\t\t确认修改?(1 是 0 否)" << endl;
cout << "\t\t\t请选择【0-1】:";
cin >> sel;
while (sel < 0 || sel>1)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 0);
else if (sel == 1)
{
t->data = tem;
cout << "\t\t\t修改成功!" << endl;
Save(L);
}
}
cout << "\n\t\t\t";
system("pause");
Delete_LinkList(L);
}
else if (sel == 3) return;
}
//显示功能
void Print_LinkList(const LinkList& L)
{
system("cls");
cout << "\t\t\t显示功能" << endl;
Node* t = L->next;
cout << "\t\t\t序号\t" << "姓名\t"<< "性别\t"<< "年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
while (t)
{
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
t = t->next;
}
cout << "\t\t\t";
system("pause");
}
//排序中sort函数第三个参数
bool compare1(const ElemType& t1, const ElemType& t2)
{
return t1.num < t2.num;
}
bool compare2(const ElemType& t1, const ElemType& t2)
{
return t1.name < t2.name;
}
bool compare3(const ElemType& t1, const ElemType& t2)
{
return t1.age < t2.age;
}
bool compare4(const ElemType& t1, const ElemType& t2)
{
return t1.relation < t2.relation;
}
//排序功能
void Sort_LinkList(LinkList& L)
{
system("cls");
cout << "\t\t\t排序功能" << endl;
Node* p = L;
cout << "\t\t\t1.按编号排序" << endl;
cout << "\t\t\t2.按姓名排序" << endl;
cout << "\t\t\t3.按年龄排序" << endl;
cout << "\t\t\t4.按分组排序" << endl;
cout << "\t\t\t5.返回主菜单" << endl;
cout << "\t\t\t请选择【1-5】:";
int cnt = 0, i = 0;
int sel;
cin>>sel;
while (sel < 1 || sel > 5)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
while (p->next)
{
p = p->next;
cnt++;
}
ElemType* arr = new ElemType[cnt];
p = L;
while (p->next)
{
p = p->next;
arr[i++] = p->data;
}
if(sel==1)
{
sort(arr, arr + cnt, compare1);
}
else if(sel==2)
{
sort(arr, arr + cnt, compare2);
}
else if(sel==3)
{
sort(arr, arr + cnt, compare3);
}
else if(sel==4)
{
sort(arr, arr + cnt, compare4);
}
else if(sel==5) return;
p = L, i = 0;
while (p->next)
{
p = p->next;
p->data = arr[i++];
p->data.num = i;
}
cout << "\t\t\t对通讯录进行排序并整理如下:" << endl;
Node* t = L->next;
cout << "\t\t\t序号\t" << "姓名\t" <<"性别\t" <<"年龄\t" << "联系电话\t" << "家庭地址\t" << "分组" << endl;
while (t)
{
cout<< "\t\t\t" << t->data.num << "\t" << t->data.name << "\t" << t->data.sex << "\t" << t->data.age << "\t" << t->data.telephone << "\t" << t->data.address << "\t\t" << t->data.relation << endl;
t = t->next;
}
Save(L);
cout << "\n\t\t\t";
system("pause");
Sort_LinkList(L);
}
//清空功能
void Clear_LinkList(LinkList& L)
{
int sel = 0;
system("cls");
cout << "\t\t\t清空功能" << endl;
cout << "\t\t\t1 确认清空通讯录" << endl;
cout << "\t\t\t2 返回主菜单" << endl;
cout << "\t\t\t请选择【1-2】:";
cin >> sel;
while (sel < 1 || sel>2)
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
if (sel == 1)
{
Node* head = L;
if (head == NULL)
{
return;
}
Node* curNode = head->next;
while (curNode != NULL)
{
Node* nextNode = curNode->next;
free(curNode);
curNode = nextNode;
}
head->next = NULL;
Save(L);
cout << "\n\t\t\t";
system("pause");
}
else if (sel == 2) return;
}
//菜单功能
void menu(LinkList& L)
{
char sel;
system("cls");
cout << "\t\t\t通讯录管理系统" << endl;
cout << "\t\t\t你可以进行以下操作:" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 1.添加联系人 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 2.删除联系人 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 3.修改联系人 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 4.查询联系人 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 5.通讯录显示 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 6.通讯录排序 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 7.通讯录清空 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t| 0.退出 |" << endl;
cout << "\t\t\t|----------------------------------------|" << endl;
cout << "\t\t\t请选择【0-7】:";
cin >> sel;
while (sel < '0' || sel>'7')
{
cout << "\t\t\t输入格式错误,请重新输入:";
cin >> sel;
}
switch (sel)
{
case '1':
Create_LinkList(L);
menu(L);
break;
case '2':
Delete_LinkList(L);
menu(L);
break;
case '3':
Modify_LinkList(L);
menu(L);
break;
case '4':
Query_LinkList(L);
menu(L);
break;
case '5':
Print_LinkList(L);
menu(L);
break;
case '6':
Sort_LinkList(L);
menu(L);
break;
case '7':
Clear_LinkList(L);
menu(L);
break;
case '0':
exit(0);
default:
menu(L);
}
}
//主函数
int main()
{
system("color 71");
LinkList L;
Init_LinkList(L);
Read(L);
menu(L);
return 0;
}
五、运行结果
1.菜单功能
2.数据读入功能
3.添加功能
4.删除功能
5.修改功能
6.查询功能
7.显示功能
8.排序功能
9.清空功能
更多推荐
所有评论(0)