赞
踩
北邮22信通一枚~
跟随课程进度每周更新数据结构与算法的代码和文章
持续关注作者 解锁更多邮苑信通专属代码~
获取更多文章 请访问专栏:
目录
利用线性表实现一个通讯里管理系统,通讯录的数据格式如下:
Struct datatype
{
int ID;
char name[10];
char ch;
char phone[13];
char addr[31];
}
***编者注:为了实现更多功能,编者已将数据域扩展成了类***
要求:
实现通讯录的建立,增加,删除,修改,查询等功能;
能够实现简单的菜单交互,可以根据用户输入的命令选择不同的操作;
能够保存每次更新的数据;
编写main()函数测试线性表的正确性;
单链表:
通讯录的增加数据、删除数据、修改数据、查询数据、打印数据、获得长度功能。
2.2.2.1单链表增加数据:
2.2.2.1.1头插法增加数据
时间复杂度:O(n)
获取插入位置的前一个结点的地址1;
新建一个节点,数据域赋值;
指针域指向地址1的下一个地址;
修改地址1的next指针,使之指向新增结点;
- template<class temp>
- inline void linklist<temp>::insert(int i, temp x)
- {
- node<temp>* p = this->front;
- if (i != 1)
- p = get(i - 1);
- if (p != NULL)
- {
- node<temp>* s = new node<temp>;
- s->data = x;
- s->next = p->next;
- p->next = s;
- }
- else
- {
- cout << "插入位置错误!" << endl;
- exit(0);
- }
- }
2.2.2.1.2自动将数据增添至链表末尾的方式增添数据
时间复杂度:O(n)
定义一个指针,遍历链表使指针指向最后一个结点;
新建一个结点,数据域赋值,指针域置空;
将指针指向的结点的next指针指向新建结点
- template<class temp>
- inline void linklist<temp>::addtorear(temp x)
- {
- node<temp>* p = this->front->next;
- while (p != NULL)
- p = p->next;
- node<temp>* s = new node<temp>;
- s->data = x;
- s->next = NULL;
- p->next = s;
- }
2.2.2.2单链表删除数据
2.2.2.2.1按位置删除结点
时间复杂度:O(n)
获取删除位置的前一个结点的地址1(指针1);
定义指向要删除的结点的指针2;
将指针1所指向的结点的next指针指向指针2所指向的结点的next指针;
删除指针2所指向的结点地址;
- template<class temp>
- inline void linklist<temp>::del(int i)
- {
- node<temp>* p = this->front;
- if (i != 1)p = get(i - 1);
- node<temp>* q = p->next;
- p->next = q->next;
- temp x = q->data;
- delete q;
- cout << "删除的数据为:" << endl;
- x.print();
- }
2.2.2.2.2按值删除结点
时间复杂度:O(n)
定义指向有效起始位置(首结点)的指针;
遍历链表,寻找数据域相同的结点的前一个结点;
按照2.2.1方法删除链表结点;
- template<class temp>
- inline void linklist<temp>::del(temp x)
- {
- int flag = 0;
- node<temp>* p = this->front;
- while (p->next != NULL)
- {
- if (p->next->data == x)
- {
- node<temp>* q = p->next;
- p->next = q->next;
- delete q;
- cout << "删除数据完毕!" << endl;
- flag = 1;
- break;
- }
- p = p->next;
- }
- if (flag == 0)
- {
- cout << "未查询到数据!" << endl;
- }
- }
2.2.2.3修改数据
时间复杂度:O(n)
获取修改数据的结点地址;
修改结点的数据域;
- template <class temp>
- inline void linklist<temp>::change(int i, temp x)
- {
- node<temp>* p = get(i);
- p->data = x;
- }
2.2.2.4查询数据
2.2.2.4.1返回值类型为指针的get函数
时间复杂度:O(n)
定义指向首结点的指针;
遍历链表,直到符合 要求时停止;
返回指针;
- template<class temp>
- node<temp>* linklist<temp>::get(int i)
- {
- node<temp>* p = this->front->next;
- int j = 1;
- while (p != NULL && j != i)
- {
- p = p->next;
- j++;
- }
- return p;
- }
2.2.2.4.2返回值为该结点在单链表中的顺序的(int类型)的函数locate:
时间复杂度:O(n)
定义指向首结点的指针;
遍历链表,直到符合要求时停止;
返回计数变量的值;如果没有找到返回-1;
- template<class temp>
- inline int linklist<temp>::locate(temp x)
- {
- node<temp>* p = this->front->next;
- int j = 1;
- while (p != NULL)
- {
- if (p->data == x)return j;
- p = p->next;
- j++;
- }
- return -1;//如果没有找到,返回无效值
- }
- #include<iostream>
- #include<iomanip>
- using namespace std;
-
- class phonebook
- {
- private:
- int ID;
- string name;
- string gender;
- string phone;
- string address;
- public:
- phonebook();
- phonebook(int, string, string, string, string);
- void getinfo(int, string, string, string, string);
- void print();
- void operator =(phonebook&);
- bool operator ==(phonebook&);
- };
-
- phonebook::phonebook()
- {
- this->ID = 0;
- this->name = "invalid_name";
- this->gender = "invalid_gender";
- this->phone = "unknown_phone_number";
- this->address = "unknown_address";
- }
-
- phonebook::phonebook(int ID, string name,
- string gender, string phone, string address)
- {
- this->ID = ID;
- this->name = name;
- this->gender = gender;
- this->phone = phone;
- this->address = address;
- }
-
- inline void phonebook::getinfo(int ID, string name,
- string gender, string phone, string address)
- {
- this->ID = ID;
- this->name = name;
- this->gender = gender;
- this->phone = phone;
- this->address = address;
- }
-
- inline void phonebook::print()
- {
- cout << setiosflags(ios::left);
- cout << "ID:" << setw(10) << this->ID;
- cout << "name:" << setw(10) << this->name;
- cout << "gender:" << setw(10) << this->gender;
- cout << "phone:" << setw(15) << this->phone;
- cout << "address:" << setw(10) << this->address;
- cout << endl;
- }
-
- inline void phonebook::operator=(phonebook& a)
- {
- this->ID = a.ID;
- this->name = a.name;
- this->gender = a.gender;
- this->phone = a.phone;
- this->address = a.address;
- }
-
- inline bool phonebook::operator==(phonebook& a)
- {
- int cnt = 0;
- if (this->ID == a.ID)cnt++;
- if (this->name == a.name)cnt++;
- if (this->gender == a.gender)cnt++;
- if (this->phone == a.phone)cnt++;
- if (this->address == a.address)cnt++;
- return (cnt == 5) ? true : false;
- }
-
- template<class temp>
- struct node
- {
- temp data;
- node<temp>* next;
- };
-
- template<class temp>
- class linklist
- {
- private:
- node<temp>* front;
- public:
- linklist()
- {
- this->front = new node<temp>;
- this->front->next = nullptr;
- }
- linklist(temp a[], int n);
- ~linklist();
- node<temp>* get(int i);
- void printlist();
- void printlength();
- int getlength();
- int locate(temp x);
- void insert(int i, temp x);
- void addtorear(temp x);
- void change(int i, temp x);
- void del(int i);
- void del(temp x);
- };
-
- template<class temp>
- linklist<temp>::linklist(temp a[], int n)
- {
- this->front = new node<temp>;
- this->front->next = NULL;
- for (int i = n - 1; i >= 0; i--)
- {
- node<temp>* s = new node<temp>;
- s->data = a[i];
- s->next = this->front->next;
- this->front->next = s;
- }
- }
-
- template<class temp>
- linklist<temp>::~linklist()
- {
- node<temp>* p = this->front;
- while (p != NULL)
- {
- this->front = p;
- p = p->next;
- delete this->front;
- }
- }
-
- template<class temp>
- node<temp>* linklist<temp>::get(int i)
- {
- node<temp>* p = this->front->next;
- int j = 1;
- while (p != NULL && j != i)
- {
- p = p->next;
- j++;
- }
- return p;
- }
-
- template <class temp>
- inline void linklist<temp>::printlist()
- {
- node<temp>* p = this->front->next;
- if (p == NULL)
- {
- cout << "p==NULL!" << endl;
- exit(0);
- }
- while (p != NULL)
- {
- p->data.print();
- p = p->next;
- }
- cout << endl;
- }
-
- template <class temp>
- inline void linklist<temp>::printlength()
- {
- node<temp>* p = this->front->next;
- int cnt = 0;
- while (p != NULL)
- {
- p = p->next;
- cnt++;
- }
- cout << endl << "有效学生信息为" << cnt << "个" << endl << endl;
- }
-
- template <class temp>
- inline int linklist<temp>::getlength()
- {
- node<temp>* p = this->front->next;
- int cnt = 0;
- while (p != NULL)
- {
- p = p->next;
- cnt++;
- }
- return cnt;
- }
-
- template<class temp>
- inline int linklist<temp>::locate(temp x)
- {
- node<temp>* p = this->front->next;
- int j = 1;
- while (p != NULL)
- {
- if (p->data == x)return j;
- p = p->next;
- j++;
- }
- return -1;//如果没有找到,返回无效值
- }
-
- template<class temp>
- inline void linklist<temp>::insert(int i, temp x)
- {
- node<temp>* p = this->front;
- if (i != 1)
- p = get(i - 1);
- if (p != NULL)
- {
- node<temp>* s = new node<temp>;
- s->data = x;
- s->next = p->next;
- p->next = s;
- }
- else
- {
- cout << "插入位置错误!" << endl;
- exit(0);
- }
- }
-
- template<class temp>
- inline void linklist<temp>::addtorear(temp x)
- {
- node<temp>* p = this->front->next;
- while (p != NULL)
- p = p->next;
- node<temp>* s = new node<temp>;
- s->data = x;
- s->next = NULL;
- p->next = s;
- }
-
- template <class temp>
- inline void linklist<temp>::change(int i, temp x)
- {
- node<temp>* p = get(i);
- p->data = x;
- }
-
- template<class temp>
- inline void linklist<temp>::del(int i)
- {
- node<temp>* p = this->front;
- if (i != 1)p = get(i - 1);
- node<temp>* q = p->next;
- p->next = q->next;
- temp x = q->data;
- delete q;
- cout << "删除的数据为:" << endl;
- x.print();
- }
-
- template<class temp>
- inline void linklist<temp>::del(temp x)
- {
- int flag = 0;
- node<temp>* p = this->front;
- while (p->next != NULL)
- {
- if (p->next->data == x)
- {
- node<temp>* q = p->next;
- p->next = q->next;
- delete q;
- cout << "删除数据完毕!" << endl;
- flag = 1;
- break;
- }
- p = p->next;
- }
- if (flag == 0)
- {
- cout << "未查询到数据!" << endl;
- }
- }
-
- int main()
- {
- system("color 0A");
- phonebook pbook[5] =
- {
- {1,"zhang","male","11111111111","a"},
- {2,"wang","female","22222222222","b"},
- {3,"li","male","33333333333","c"},
- {4,"zhao","female","44444444444","d"},
- {5,"liu","male","55555555555","e"}
- };
- linklist<phonebook>list(pbook, 5);
- while (1)
- {
- label0:
- cout << setw(41) << "欢迎来到通讯录管理系统!" << endl;
- cout << setw(40) << "*****增加数据请按1*****" << endl;
- cout << setw(40) << "*****删除数据请按2*****" << endl;
- cout << setw(40) << "*****修改数据请按3*****" << endl;
- cout << setw(40) << "*****查询数据请按4*****" << endl;
- cout << setw(40) << "*****显示数据请按5*****" << endl;
- cout << setw(40) << "*****退出查询请按6*****" << endl;
- cout << endl << "请输入序号:";
- int n0;
- cin >> n0;
- int flag = 1;
- switch (n0)
- {
- case 1:
- {
- cout << setw(40) << "欢迎来到数据增加界面!" << endl;
- cout << "请输入您想增加到通讯录中的先生/女士信息:" << endl;
- cout << "注意,请依次输入ID,姓名,性别," <<
- "电话号码和家庭住址,所有信息占一行" << endl;
- int ID; string name, gender, phone, address;
- cin >> ID >> name >> gender >> phone >> address;
- phonebook record0(ID, name, gender, phone, address);
- cout << "请输入您想将数据插入的位置序号:" << endl;
- int n1;
- cin >> n1;
- int length = list.getlength();
- if (n1 <= length)
- list.insert(n1, record0);
- else
- list.addtorear(record0);
- cout << "插入后的通讯录显示为:" << endl;
- list.printlist();
- break;
- }
- case 2:
- {
- cout << setw(40) << "欢迎来到数据删除界面!" << endl;
- label1:
- cout << "按顺序删除请按0,按值删除请按1" << endl;
- int n2;
- cin >> n2;
- switch (n2)
- {
- case 0:
- {
- int order;
- cout << "请输入删除的数据在通讯录中的顺序:";
- cin >> order;
- list.del(order);
- cout << "删除后的通讯录显示为:" << endl;
- list.printlist();
- break;
- }
- case 1:
- {
- cout << "请输入您想删除的先生/女士信息:" << endl;
- cout << "注意,请依次输入ID,姓名,性别," <<
- "电话号码和家庭住址,所有信息占一行" << endl;
- int ID; string name, gender, phone, address;
- cin >> ID >> name >> gender >> phone >> address;
- phonebook record1(ID, name, gender, phone, address);
- list.del(record1);
- cout << "删除后的通讯录显示为:" << endl;
- list.printlist();
- break;
- }
- default:
- {
- cout << "输入错误!" << endl;
- goto label1;
- break;
- }
- }
-
- break;
- }
- case 3:
- {
- cout << setw(40) << "欢迎来到数据修改界面!" << endl;
- cout << "请输入您想修改的先生/女士在通讯录中的顺序:";
- int n3;
- cin >> n3;
- cout << "请输入您想修改先生/女士信息:" << endl;
- cout << "注意,请依次输入ID,姓名,性别," <<
- "电话号码和家庭住址,所有信息占一行" << endl;
- int ID; string name, gender, phone, address;
- cin >> ID >> name >> gender >> phone >> address;
- phonebook record2(ID, name, gender, phone, address);
- list.change(n3, record2);
- cout << "修改后的通讯录为:" << endl;
- list.printlist();
- break;
- }
- case 4:
- {
- label2:
- cout << setw(40) << "欢迎来到数据查询界面!" << endl;
- cout << "请输入您想查询的先生/女士信息:" << endl;
- cout << "注意,请依次输入ID,姓名,性别," <<
- "电话号码和家庭住址,所有信息占一行" << endl;
- int ID; string name, gender, phone, address;
- cin >> ID >> name >> gender >> phone >> address;
- phonebook record3(ID, name, gender, phone, address);
- int pos = list.locate(record3);
- if (pos == -1)
- {
- cout << "该人员不在通讯录内,请问您是否继续查询?" << endl;
- cout << "如果选择继续查询请按1,不继续查询请按0" << endl;
- int n4;
- cin >> n4;
- switch (n4)
- {
- case 1:
- {
- goto label2;
- break;
- }
- case 0:
- break;
- default:
- break;
- }
- }
- else
- {
- cout << endl << "您查找的人员在通讯录中,"
- "在通讯录中的顺序为第" << pos << "个" << endl << endl;
- }
- break;
- }
- case 5:
- {
- cout << setw(40) << "欢迎来到数据显示界面!" << endl;
- list.printlength();
- cout << "您当前通讯录列表打印如下:" << endl;
- list.printlist();
- break;
- }
- case 6:
- {
- return 0;
- }
- default:
- {
- flag = 0;
- break;
- }
- }
- if (flag == 0)
- {
- cout << "上次输入无效,请重新输入!" << endl;
- goto label0;
- }
- }
- return 0;
- }
- /*
- 初始数据:
- 1 zhang male 11111111111 a
- 2 wang female 22222222222 b
- 3 li male 33333333333 c
- 4 zhao female 44444444444 d
- 5 liu male 55555555555 e
- 增加数据样例:
- 6 meng female 66666666666 f
- */
代码效果图:
程序运行结果:
开始界面:用户输入功能选择的键值;
对每个界面均有输入错误处理机制,使用了label goto语句;
部分功能为了更好满足用户需求,实现了switch语句的嵌套;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。