1.简要描述你是如何选择数据结构的逻辑结构和存储结构的?
把通信录抽象成一个线性表,每个通话人(包括姓名、电话)作为该线性表的一个元素。由于通信数据较多,需要频繁的插入和删除操作,故采用链式存储结构。
2.通讯录管理系统
(1)通信录首页
(2)建立通信录(功能选择:0)
张三 13407846666 苏珊 13407846689
胡琦琦 13407857777 李丹丹 13407842893
张文文 13407846890 李志强 13407846690
林相知 13407842390
(3)查看建立后的通信录信息(功能选择:4)
注:以名字为关键字对通讯录信息升序排列。
(4)添加通信录信息(功能选择:1)
段于 12783947923
添加新信息后仍然以姓名关键字对通讯录信息升序排列
(5)查询通信录信息(功能选择:2)
分别用姓名、电话这两种方式查询:张三 13407857777
(6)删除通讯录信息(功能选择:3)
删除名字为张三的通讯信息。
(7)清空通讯录信息(功能选择:5)
(8)退出通讯录管理系统(功能选择:6)
3.运行代码
#include<iostream>
#include<conio.h>
#include<iomanip>
#include<windows.h>
#include<time.h>
#include<string>
using namespace std;
/*****结构框架*****/
//定义包含姓名、电话号码的结构体
typedef struct
{
string name;//姓名
string tel;//电话号码
}DataType;
typedef struct node
{
DataType data;
struct node *next;
}ListNode,*LinkList;
/*****单链表的初始化*****/
void InitList(LinkList &L)
{
L=new ListNode;
L->next=NULL;
}
/****通讯录的排序******/
void TelSort(LinkList &L)
{
ListNode *p, *q;
string t;
p = L->next;//p指向首元结点
while(p!=NULL)//第一重循环将p的位置固定下来,进入第二重循环与后面的遍历指针p所指向的结点之间相互比较大小
{
q = p->next;//将q指向p的下一个结点,进行数据之间的大小比较
while (q != NULL)//第二重循环就是不断将指针q后移,与p所指向的结点数据进行大小比较,数据互换
{
if (p->data.name>q->data.name)
{
t = p->data.name;//将数据寄存在t中,进行互换
p->data.name = q->data.name;
q->data.name = t;
}
q = q->next;//遍历
}
p = p->next;
}
}
/****通讯录的建立******/
void TelBuild(LinkList &L)
{
string p_name;
bool flag=false;
ListNode *p;
cout<<">> 输入编号为0时,结束通讯录的建立";
cout<<endl<<"-----------------------------"<<endl;
while(!flag)
{
cout<<">>姓名:";
cin>>p_name;
if(p_name!="0")
{
p=new ListNode;
p->data.name=p_name;
cout<<">>电话:";
cin>>p->data.tel;
p->next=L->next;
L->next=p;
cout<<"-----------------------------"<<endl;
}
else
{
system("cls");
cout<<endl<<">>>>> 建立通讯录成功! <<<<<"<<endl;
Sleep(1000);
break;
}
}
}
/****通讯录的插入*****/
void TelInsert(LinkList &L)
{
ListNode *p=L;
bool flag=true;//当flag为true是插入循环实现,反之则退出插入功能
while(flag)
{
p=new ListNode;
cout<<">>>>分别输入姓名、电话:";
cout<<endl<<"-----------------------------"<<endl;
cout<<">>>>姓名:";
cin>>p->data.name;
cout<<">>>>电话:";
cin>>p->data.tel;
p->next=L->next;
L->next=p;
cout<<"-----------------------------"<<endl;
cout<<">>添加成功!是否继续添加(Y/N):";
char option;//供用户选择是否继续插入
cin>>option;
system("cls");//清屏
if(option=='Y'||option=='y')
flag=true;
else
flag=false;
}
}
/*****通讯录的查询*****/
void TelSearch(LinkList L)
{
ListNode *p=L->next,*q;
int i;//i为供用户选择查询方式的输入选项
bool UnFound,Found,InputError,flag;
//1.falg为true重复查询,为false退出查询,若为true才进行下一步,检查InputError是否合法
//2.InputError检查输入是否合法,若合法才进行下一步即编号/姓名的匹配
//3.Found为true时,显示查到的记录,UnFound为false时,显示无相关记录
flag=true;
char option='Y';
string p_name;//查询方式1:姓名
string p_tel;//查询方式2:电话
/**步骤1.**/
while(flag)
{
if(!L->next)
{
cout<<">>>>通信录为空!"<<endl;
break;
}
else
{//当通讯录非空
while(option=='Y'||option=='y')
{
int count=0;//count记录通讯记录总数
InputError=false;//InputError默认为false即无错误
cout<<">>>>请选择1.姓名或2.电话进行查询:";
cin>>i;
/**步骤2.**/
switch(i)//利用switch语句实现多种查询方式的使用
{
case 1:
cout<<">>>>请输入姓名:";
cin>>p_name;
break;
case 2:
cout<<">>>>请输入电话:";
cin>>p_tel;
break;
default:
cout<<">>>>输入错误,请重新输入!"<<endl;
InputError=true;//当输入发生错误,InputError设为true即有错误
break;
}
if(!InputError)//当InputError为false即无错误时,才进行编号/姓名的匹配
{
p=L->next;
UnFound=false;//UnFound默认为false
while(p)
{
Found=false;//Found默认为false
/**步骤3.**/
switch(i)//利用switch语句进行对应匹配
{
case 1:
if(p_name==p->data.name){
Found=UnFound=true;//当匹配到对应编号,Found改为true
q=p;
}
p=p->next;
break;
case 2:
if(p_tel==p->data.tel){
Found=UnFound=true;//当匹配到对应姓名,Found改为true
q=p;
}
p=p->next;
break;
default:
break;
}
if(Found)//当Found为true即匹配到了数据
{
if(count==0)//显示表头
cout<<"-----------------------------"<<endl<<"查询到学生信息如下:"<<endl;
cout<<"姓名:"<<q->data.name<<endl;
cout<<"电话:"<<q->data.tel<<endl;
cout<<"-----------------------------"<<endl;
count++;
}
}
if(!UnFound)//UnFound为false才显示
cout<<"-----------------------------"<<endl<<"查无此人!"<<endl<<"-----------------------------"<<endl;
cout<<">> 共查询到"<<count<<"条记录..."<<endl;
cout<<">> 是否继续查询(Y/N):";
cin>>option;
system("cls");//清屏
if(option=='Y'||option=='y')
flag=true;
else
flag=false;
}
}
}
}
}
/*****通讯录的删除*****/
void TelDelete(LinkList &L)
{
ListNode *p,*q;
string p_name;//p_name为用户想要删除的记录的姓名
char option='Y';//option为Y是循环删除功能,默认为Y
bool Found,flag;//Found检查是否找到用户要输出的记录的序号。flag为true时,循环删除功能
flag=true;//默认为true
while(flag)
{
while( option=='Y'||option=='y')
{
int count=0;//count记录删除的记录总数
Found=false;//Found默认为fasle
p=L;
q=p->next;
if(!q)
{
cout<<">>>>通讯录已为空...";
Sleep(1000);
system("cls");
return;
}
cout<<">>>>输入删除姓名:";
cin>>p_name;
while(q)
{
if(p_name==q->data.name)
{//当匹配到记录
if(count==0)//打印表头
{
cout<<endl<<"删除信息如下:";
cout<<endl<<"-----------------------------";
}
cout<<"姓名:"<<q->data.name<<endl;
cout<<"电话:"<<q->data.tel<<endl;
cout<<"-----------------------------";
p->next=q->next;
delete q;
Found=true;//当匹配到记录,Found设为true
count++;
q=p->next;
continue;
}
else
{
p=p->next;
q=p->next;
}
}
if(!Found)
{
cout<<"-----------------------------"<<endl
<<">> 查无此人!"<<endl<<"-----------------------------";
}
if(p)
{
cout<<endl<<">>>>共删除"<<count<<"条记录..."<<endl;
cout<<">>>>是否继续删除(Y/N):";
cin>>option;
system("cls");
if(option=='Y'||option=='y')
flag=true;
else
flag=false;
}
}
}
}
/*****输出通讯录全部信息*****/
void TelOutput(LinkList L)
{
ListNode *p=L->next;
int count=0;
//打印表头
cout<<" ========================================="<<endl;
cout<<"┃ * 通讯录的全部信息 * ┃"<<endl;
cout<<"┃ 姓名 电话 ┃"<<endl;
cout<<" ========================================="<<endl;
if(L->next)
{
while(p)
{
cout<<"┃\t"<<setw(5)<<p->data.name
<<"\t┃\t"<<setw(11)<<p->data.tel<<" ┃";
p=p->next;
count++;
if(p)
cout<<endl;
}
cout<<endl<<" ========================================="<<endl;
}
else cout<<"┃ 通讯录为空! ┃"<<endl
<<" ========================================="<<endl;
cout<<endl<<">>>>> 共"<<count<<"条记录...<<<<<"<<endl;
cout<<">>>>> 按任意键返回主界面...<<<<<"<<endl;
while(char a=_getch())//清屏
{
system("cls");
return;
}
}
/*****清空通讯录全部信息*****/
void TelClear(LinkList &L)
{
ListNode *p,*q;
p=L->next;
while(p!=NULL)
{
q=p->next;
free(p);
p=q;
}
L->next=NULL;
system("cls");
cout<<endl<<">>>>> 清空通讯录成功! <<<<<"<<endl;
}
//图画显示
void TelPrint()
{
struct tm *ptr;
time_t it;
it=time(NULL);
ptr=localtime(&it);
cout<<endl;
cout<<" "<<ptr->tm_year+1900<<"年"<<ptr->tm_mon+1<<"月"<<ptr->tm_mday<<"日"<<endl;//显示系统日期
cout<<endl;
cout<<" Newbee"<<endl;
cout<<endl;
cout<<" 通讯录管理系统"<<endl<<endl<<endl;
cout<<" ============================================================"<<endl;
cout<<"┃ * 欢迎进入通讯录管理系统 * ┃"<<endl<<endl;
cout<<"┃ >> 0.通讯录的建立 << ┃"<<endl;
cout<<"┃ >> 1.通讯录的添加 << ┃"<<endl;
cout<<"┃ >> 2.通讯录的查询 << ┃"<<endl;
cout<<"┃ >> 3.通讯录的删除 << ┃"<<endl;
cout<<"┃ >> 4.通讯录的查看 << ┃"<<endl;
cout<<"┃ >> 5.通讯录的清空 << ┃"<<endl;
cout<<"┃ >> 6.退出管理系统 << ┃"<<endl;
cout<<" ============================================================"<<endl;
cout<<endl<<" >>>>>功能选择(0~5):";
}
/*****主界面窗口*****/
int main()
{
LinkList L;
InitList(L);
int flag=1;//flag=1程序继续运行,flag=0程序结束
while(flag)
{
int option;//功能选择的输入
TelPrint();//显示图画
cin>>option;//输入要实现功能
system("cls");
switch(option)//根据输入数字不同实现相应功能
{
case 0:
TelBuild(L);//建立
break;
case 1:
TelInsert(L);//插入
break;
case 2:
TelSearch(L);//查询
break;
case 3:
TelDelete(L);//删除
break;
case 4:
TelSort(L);
TelOutput(L);//输出
break;
case 5:
TelClear(L);
break;
case 6:
flag=0;//结束程序
cout<<" >> 程序结束:-D"<<endl;
Sleep(1000);
break;
default:
cout<<">> 输入错误,请重新输入!"<<endl;
break;
}
}
return 0;
}