数据结构实验一 通讯录
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构实验报告
实验名称:实验一——线性表
学生姓名:大学霸
班级:xxxxxxxxxx
班内序号:xx
学号:xxxxxxxxxx
日期:2012年11月1日
1.实验要求
实验目的:
1.学习指针,模板类,异常处理的使用;
2.掌握线性表的操作实现方法;
3.培养使用线性表解决实际问题的能力。
实验内容:
利用线性表实现一个通讯录管理,通信录的数据格式如下:
struct DataType
{
int ID; //编号
char name[10]; //姓名
char ch; //性别
char phone[13]; //电话
char addr[31]; //地址
};
具体要求:
1.实现通信录的建立、增加、删除、修改、查询等功能
2.能够实现简单的菜单交互,即可以根据用户输入的命令,选择不同的操作
3.能够保存每次更新的数据
4.编写main()函数测试操作的正确性
2. 程序分析
编程完成通讯录的一般性管理工作如通讯录中记录的增加、修改、查找、删除、输出等功能。
每个记录包含姓名、电话号码、住址等个人基本信息。
用《数据结构》中的链表做数据结构结合c语言基本知识编写一个通讯录管理系统。
本程序为使用方便,几乎不用特殊的命令,只需按提示输入即可,适合更多的用户使用。
对于建立通讯录管理系统,则需了解并掌握数据结构与算法的设计方法,提高综合运用所学的理论知识和方法独立分析和解决问题的能力。
2.1 存储结构
节点结构:
2.2 关键算法分析
本实验从整体上分为七大模块:
(1)输入联系人信息;(2)添加联系人信息;(3)查找联系人信息;(4)查看联系人信息;(5)删除联系人信息;(6)修改联系人信息;(7)退出通讯录管理。
通讯录系统图
2.2.1通讯录的建立
伪代码:
1.在堆中申请新的结点;
2.新节点的数据域为a[i];
3.将新节点加入到链表中;
4.修改尾指针;
5.全部结点插入后需要将终结结点的指针域设为空。
C++实现:
ContactBook::ContactBook(DataType a[],int n)//尾插法
{
front=new Node;
rear=new Node;
rear=front; //构造空单链表
for(int i=0;i<n;i++)
{
Node * s=new Node; //建立新节点
s->data=a[i]; //写入数据域
rear->next=s; //将新节点加入到链表中
rear=s; //修改尾指针
}
rear->next=NULL; //终端节点的指针域设为空
}
时间复杂度:o(n)
2.2.2通讯录的插入
伪代码:
插入为建立的一种特殊形式,即插入一个单独的结点,方法与上述类似
C++实现:
void ContactBook::Add(DataType a)//尾插法
{
Node * s=new Node;
s->data=a;
rear->next=s;
rear=s;
rear->next=NULL;
}
时间复杂度:o(1)
2.2.3按ID查找
查找操作是指用户输入要查找的用户的ID,系统该函数内找到该用户,返回用户数据域的指针,在主函数中输出该用户的全部信息。
伪代码:
1.初始化工作指针p;
2.循环以下操作直到p为空或找到用户
1.如果p的数据等于i,则返回P的数据域指针;
2.P指针指向下一个节点;
3.若找不到返回空指针。
C++实现:
//通讯簿按ID查找
DataType * ContactBook::Get(int i)
{
Node * p=front->next;
while(p)
{
if(p->data.ID==i)return &(p->data); //根据ID找到被查元素,返回位置
p=p->next;
}
return NULL; //若找不到,返回空指针
}
时间复杂度:o(n)
2.2.4通讯录的删除
删除操作是指根据用户输入要删除用户的ID,找到该用户结点,返回该用户的数据域,删除此节点
伪代码:
1.从第一个节点开始,查找到要删用户的的前一个用户节点,设P指向该节点;
2.设q指向要删除的用户:q=p->next;
3.摘链:p->next=q->next;
4.保存q节点的数据域:x=q->data;
5.释放q节点:deleteq;
要指出的是若在整个通讯录找不到该ID,直接跳过删除步骤,输出查无此人
C++实现:
DataType ContactBook::Delete(int i)
{
Node * p=front;
while(p->next)
{
if(p->next->data.ID==i)break; //找到要删除的用户,跳出循环
p=p->next;
}
Node * q=p->next; //找到该用户
if(q)
{
p->next=q->next;
DataType x=q->data; //记录用户信息
delete q; //删除用户
cout<<" 删除成功!"<<endl;
return x;
}
else{
cout<<" 该用户不存在!"<<endl;
}
}
时间复杂度:o(n)
2.2.5通讯录的修改
当用户要进行修改用户操作时,会在主函数输入要修改用户的ID,调用查询模块,若用户存在,系统会显示找到的用户信息,然后要求依次输入该用户新的的编号,姓名,性别,手机号,地址,输入这些后,用户信息被修改
C++实现:
//通讯簿修改
void ContactBook::Modify(DataType a,int i)
{
DataType * p=Get(i); //按ID找到要修改的用户* p=a; //修改用户的个人数据}
时间复杂度:o(n)
2.2.6通讯录的遍历显示
用户选择输出通讯录,系统会依次输出所有用户的信息
输出的基本思想是:只要将表头的指针赋给一个指针变量p,然后用p向后扫描,直到表尾,p为空值。
C++实现:
//通讯簿遍历
void ContactBook::PrintList()
{
Node * p=front->next;
cout<<"您的通讯簿信息如下:"<<endl;
cout<<"-------------------------------"<<endl;
while(p)
{
cout<<p->data.ID<<" "<<p-><<" "<<p->data.ch<<" "<<p->data.phone<<" "<<p->data.addr;
cout<<endl;
cout<<"-------------------------------"<<endl;
p=p->next;
}
}
时间复杂度:o(n)
2.2.7通讯录的析构
通讯录的析构即为单链表的析构,比较简单
C++实现:
//析构函数
ContactBook::~ContactBook() {
Node *p=front;
while(p){
front=p;
p=p->next;
delete front;
}
}
时间复杂度:(n)
2.3 其他
3. 程序运行结果
主函数流程图:
测试截图:
1.建立通讯簿
2.添加新用户
3.查找用户
4.删除用户
5.查看所有用户
6.修改已有用户
7.退出通讯簿管理系统
4. 总结
通过这次的数据结构上机试验,让我回顾了有关线性表这一章的知识,学会使用线性表解决实际问题,让我有了更深的认识和了解,能灵活的使用,同时也发现了自己的不足,有些地方理解还不够深刻,出现了不少问题
调试时问题主要出在内存错误上,有时指针悬挂,有时尾指针指向错误,这些都需要一步步耐心的调试才能发现,以后编程我会注意改正这些
依照实验要求,在不同操作时加入了异常处理,比如要查找,删除,修改用户时,如果输入的ID不存在,系统会报错并终止操作,提高了系统的操作性
这次设计的通讯簿管理系统还有些可以改进的地方,比如加入文件流后可以将每次输入的信息保存在后台的一个文件里,每次使用时读取这个文件内的信息,实现了保存每次更新的数据。
我对于文件流的使用还不是很熟悉,所以没来及加入这项功能;还有在查询这一块,只实现了按编号查询,还未加入按姓名查找。
附:所有源程序
#include<iostream>
using namespace std;
//个人数据结构体
struct DataType{
int ID; //用户ID;
char name[10]; //姓名
char ch; //性别
char phone[13]; //手机号码char addr[31]; //地址
};
//用户结点
struct Node{
DataType data;
struct Node * next;
};
//通讯簿类声明
class ContactBook
{
public:
ContactBook(){front=new Node;rear=new Node;front->next=NULL;rear=front;} ContactBook(DataType a[],int n); //建立
~ContactBook(); //析构
void Add(DataType a); //添加
DataType * Get(int i); //查找
DataType Delete(int i); //删除
void Modify(DataType a,int i); //修改
void PrintList(); //遍历private:
Node * front; //头结点
Node * rear; //尾结点
};
//通讯簿的建立
ContactBook::ContactBook(DataType a[],int n)//尾插法
{
front=new Node;
rear=new Node;
rear=front;
for(int i=0;i<n;i++)
{
Node * s=new Node;
s->data=a[i];
rear->next=s;
rear=s;
}
rear->next=NULL;
}
//通讯簿的添加
void ContactBook::Add(DataType a)//尾插法
{
Node * s=new Node;
s->data=a;
rear->next=s;
rear=s;
rear->next=NULL;
}
//通讯簿按ID查找
DataType * ContactBook::Get(int i)
{
Node * p=front->next;
while(p)
{
if(p->data.ID==i)return &(p->data); //根据ID找到被查元素,返回位置
p=p->next;
}
return NULL; //若找不到,返回空指针
}
//通讯簿修改
void ContactBook::Modify(DataType a,int i)
{
DataType * p=Get(i); //按ID找到要修改的用户* p=a; //修改用户的个人数据}
//通讯簿删除
DataType ContactBook::Delete(int i)
{
Node * p=front;
while(p->next)
{
if(p->next->data.ID==i)break; //找到要删除的用户,跳出循环
p=p->next;
}
Node * q=p->next; //找到该用户
if(q)
{
p->next=q->next;
DataType x=q->data; //记录用户信息
delete q; //删除用户
cout<<" 删除成功!"<<endl;
return x;
}
else{
cout<<" 该用户不存在!"<<endl;
}
}
//通讯簿遍历
void ContactBook::PrintList()
{
Node * p=front->next;
cout<<"您的通讯簿信息如下:"<<endl;
cout<<"-------------------------------"<<endl;
while(p)
{
cout<<p->data.ID<<" "<<p-><<" "<<p->data.ch<<" "<<p->data.phone<<" "<<p->data.addr;
cout<<endl;
cout<<"-------------------------------"<<endl;
p=p->next;
}
}
//析构函数
ContactBook::~ContactBook()
{
Node *p=front;
while(p){
front=p;
p=p->next;
delete front;
}
}
void main()
{
DataType a[5]={{1001,"张一",'m',"188****1881","北京"},
{1002,"王二",'m',"188****1882","上海"},
{1003,"周三",'m',"188****1883","广州"},
{1004,"陈四",'f',"188****1884","天津"},
{1005,"赵五",'f',"188****1885","南京"}};
ContactBook My(a,5);
int choose;
do{
cout<<" 通讯簿管理系统"<<endl;
cout<<"-------------------------------"<<endl;
cout<<" 1.建立我的通讯簿"<<endl;
cout<<" 2.添加通讯簿的成员"<<endl;
cout<<" 3.查找通讯簿的成员"<<endl;
cout<<" 4.删除通讯簿的成员"<<endl;
cout<<" 5.查看我的通讯簿"<<endl;
cout<<" 6.修改通讯簿的成员"<<endl;
cout<<" 0.退出通讯簿管理系统"<<endl;
cout<<"-------------------------------"<<endl;
cout<<" 请选择:";
cin>>choose;
switch(choose)
{
case 1:
cout<<endl<<" 通讯簿建立成功"<<endl<<endl;
break;
case 2:
DataType x;
cout<<"请输入新用户的ID、姓名、性别(m/f)、手机号、住址"<<endl;
cin>>x.ID>>>>x.ch>>x.phone>>x.addr;
My.Add(x);
cout<<" 新用户添加成功!"<<endl<<endl;
break;
case 3:
int search;
cout<<" 请输入要查找用户的ID:";
cin>>search;
if(My.Get(search)){
cout<<" 查找到的信息如下:"<<endl;
cout<<"-------------------------------"<<endl;
cout<<My.Get(search)->ID<<" "<<My.Get(search)->name<<" "<<My.Get(search)->ch<<" "<<My.Get(search)->phone<<"
"<<My.Get(search)->addr;
cout<<endl;
cout<<"-------------------------------"<<endl;
}
else
cout<<" 该用户不存在!"<<endl;
cout<<endl;
break;
case 4:
int del;
cout<<" 请输入要删除用户的ID: ";
cin>>del;
if(My.Get(del)){
cout<<"-------------------------------"<<endl;
cout<<My.Get(del)->ID<<" "<<My.Get(del)->name<<" "<<My.Get(del)->ch<<" "<<My.Get(del)->phone<<" "<<My.Get
(del)->addr;
cout<<endl;
cout<<"-------------------------------"<<endl;
cout<<" 确定删除该用户?(y/n): ";
char IsDel;
cin>>IsDel;
if(IsDel=='y')
My.Delete(del);
else
cout<<" 取消删除!"<<endl;;
cout<<endl;}
else
cout<<" 用户不存在!"<<endl<<endl;
break;
case 5:
My.PrintList();
break;
case 6:
int mod;
cout<<" 请输入要修改用户的ID: ";
cin>>mod;
if(My.Get(mod)){
DataType x;
cout<<"请输入修改后的ID、姓名、性别(m/f)、手机号、住址"<<endl;
cin>>x.ID>>>>x.ch>>x.phone>>x.addr;
My.Modify(x,mod);
cout<<" 修改成功!"<<endl<<endl;;
}
else
cout<<" 该用户不存在!"<<endl<<endl;
break;
case 0:
cout<<" 退出成功!"<<endl;
break;
default:
cout<<" 输入有误!"<<endl<<endl;
};
}while(choose!=0);
}
实验报告总字数要求不少于1000字。