我是周日下午开始写的,本来觉得这个作业很简单,老师只是说用class类写一个通讯录管理系统,没指明具体用啥数据结构,俺又不会用对象数组(明明ppt上有,只是偷懒不想看),所以就打算用类实现链表来完成这个系统。
很快啊,用了不到一个小时就写了个大框架,然后发现,tnnd我这个链表只能存一个人(当场气晕),事实上都不能叫链表了。然后啊,就去寻求万能的网友们的帮助,于是就发现了这篇大神写的博客,这里给下地址(16条消息) c++数据结构与算法(10)——链表(使用class实现)_北顾+的博客-CSDN博客_链表类
侵删(蒟蒻瑟瑟发抖)
namo接下来就来看看俺的bug系统8
目录
一、Node类的创建
class List;
class Node
{
int data;
string name;
string tel;
string qq;
string address;
string email;
Node* next;
public:
friend class List;
Node(string,string,string,string,string);
};
因为是用类写的嘛,所以数据的隐蔽性是需要的,因此属性之类的都设为private,同时还需要一个next指针(见链表定义),而且这里有一个小细节,我们所需要构建的List链表类是需要设为Node类的友元类,如此List类才可以访问Node类的私有数据
还要注意一点,Node类的构造函数最好是给数据赋一个初始值,防止它乱跳数据,如下
Node::Node(string name,string tel,string qq,string email,string address)
{
this->name = name;
this->tel = tel;
this->qq = qq;
this->email = email;
this->address = address;
next = nullptr;
}
二、List类的创建(重要)
class List
{
Node *head;
public:
List();
void Insert(string,string,string,string,string);
void Show();
void DeleteByName(string);
void DeleteByQQ(string);
void DeleteByTel(string);
void SearchByName(string);
void SearchByQQ(string);
void SearchByTel(string);
void ModifyByName(string,string,string,string,string);
void ModifyByQQ(string,string,string,string,string);
void ModifyByTel(string,string,string,string,string);
};
嗯...这个链表我写的不是很完全,我是采用的头插法进行创建,遍历以及删除的,所以这里需要一个head指针并把它私有化。
同样的,LIst的构造函数也需要赋一个初始值,只需要把head置空就可
List::List()
{
head = nullptr;
}
然后,就是一些链表的基本用法,就像插入啊,删除啊,遍历啊啥的,看看就可,很简单。
如,这是链表的插入(我这里有药老师要求有三个数据是唯一的,所以在插入的时候遍历了一遍判断是否有重复元素)
void List::Insert(string name,string tel,string qq,string email,string address)
{
Node* previous = nullptr;
Node* current;
for(current = head; current && (current->name != name || current->tel != tel || current->qq != qq); previous = current,current = current->next);
if (current == nullptr)
{
Node* newNode = new Node(name,tel,qq,email,address);
newNode->next = head;
head = newNode;
}
}
如果不要求去重的话,可以看下面这一段
Node* newNode = new Node(要存的数据);
newNode->next = head;
head = newNode;
然后,嗯....删除,如下
void List::DeleteByName(string name)
{
Node* previous = nullptr; //上一个结点
Node* current; //当前结点
for(current = head;
current && current->name != name;
previous = current, current = current->next);
if(current) //如果存在
{
if(previous)
previous->next = current->next; //直接把上一个结点的next指向下一个结点
else
head = head->next; //如果上一个结点时头结点
delete current;
}
}
也是从头结点开始遍历,找到要删除的位置,直接把它的上一个结点指向下一个结点就可以了
就像这样
然后就是查找...
void List::SearchByName(string name)
{
Node* previous = nullptr;
Node* current;
for(current = head;
current && current->name != name;
previous = current, current = current->next);
if(current)
{
cout << "姓名\t电话号码\t\tQQ\t\tEmail\t\t籍贯" << endl;
cout << current->name <<"\t"<< current->tel <<"\t"<< current->qq <<"\t"<< current->address <<"\t"<< current->email <<"\t"<< endl;
}
else
{
cout << "不存在该名人类" << endl;
}
}
和删除类似,先遍历到该位置之后输出即可,其实这里我本想用类似于这种形式的
Node* Find(T)
{ Node*p; //代表对应位置的结点指针
return p;
}
但很可惜,这是类,用这种方式的话由于数据都是私有的,所以时没办法访问到的(蒟蒻大哭)
最后就是输出整个链表,从头到尾遍历输出一遍就好
void List::SearchByName(string name)
{
Node* previous = nullptr;
Node* current;
for(current = head;
current && current->name != name;
previous = current, current = current->next);
if(current)
{
cout << "姓名\t电话号码\t\tQQ\t\tEmail\t\t籍贯" << endl;
cout << current->name <<"\t"<< current->tel <<"\t"<< current->qq <<"\t"<< current->address <<"\t"<< current->email <<"\t"<< endl;
}
else
{
cout << "不存在该名人类" << endl;
}
}
三、完整代码
有些注释没删,将就着看吧(你就是个大懒虫
#include <iostream>
using namespace std;
class List;
class Node
{
int data;
string name;
string tel;
string qq;
string address;
string email;
Node* next;
public:
friend class List;
Node(string,string,string,string,string);
};
Node::Node(string name,string tel,string qq,string email,string address)
{
this->name = name;
this->tel = tel;
this->qq = qq;
this->email = email;
this->address = address;
next = nullptr;
}
class List
{
Node *head;
public:
List();
void Insert(string,string,string,string,string);//插入数据
void Show();//显示数据
void DeleteByName(string);//删除数据
void DeleteByQQ(string);//删除数据
void DeleteByTel(string);//删除数据
void SearchByName(string);
void SearchByQQ(string);
void SearchByTel(string);
void ModifyByName(string,string,string,string,string);
void ModifyByQQ(string,string,string,string,string);
void ModifyByTel(string,string,string,string,string);
};
List::List()
{
head = nullptr;
}
void List::Insert(string name,string tel,string qq,string email,string address)
{
Node* previous = nullptr;
Node* current;
for(current = head; current && (current->name != name && current->tel != tel && current->qq != qq); previous = current,current = current->next);
if (current == nullptr)
{
//新建一个待插入的节点
Node* newNode = new Node(name,tel,qq,email,address);
//让头节点变为新节点的下一个节点指
newNode->next = head;
//让新插入的节点变为头节点
head = newNode;
}
}
void List::DeleteByName(string name)
{
Node* previous = nullptr;//保存上一个节点
Node* current;//保存当前节点
//空循环,遍历链表,直到找到要删除的值,用previous保存要删除的节点的上一个节点
for(current = head;
current && current->name != name;
previous = current, current = current->next);
if(current)
{
//如果previous为null的话,说明要删除的节点为头节点,因为头节点没有上一个节点
if(previous)//不是头节点
previous->next = current->next;
else // 是头节点的话直接指向头节点的下一节点即可
head = head->next;
delete current;//释放内存
}
}
void List::DeleteByQQ(string qq)
{
Node* previous = nullptr;//保存上一个节点
Node* current;//保存当前节点
//空循环,遍历链表,直到找到要删除的值,用previous保存要删除的节点的上一个节点
for(current = head;
current && current->qq != qq;
previous = current, current = current->next);
if(current)
{
//如果previous为null的话,说明要删除的节点为头节点,因为头节点没有上一个节点
if(previous)//不是头节点
previous->next = current->next;
else // 是头节点的话直接指向头节点的下一节点即可
head = head->next;
delete current;//释放内存
}
}
void List::DeleteByTel(string tel)
{
Node* previous = nullptr;//保存上一个节点
Node* current;//保存当前节点
//空循环,遍历链表,直到找到要删除的值,用previous保存要删除的节点的上一个节点
for(current = head;
current && current->tel != tel;
previous = current, current = current->next);
if(current)
{
//如果previous为null的话,说明要删除的节点为头节点,因为头节点没有上一个节点
if(previous)//不是头节点
previous->next = current->next;
else // 是头节点的话直接指向头节点的下一节点即可
head = head->next;
delete current;//释放内存
}
}
void List::SearchByName(string name)
{
Node* previous = nullptr;
Node* current;
for(current = head;
current && current->name != name;
previous = current, current = current->next);
if(current)
{
cout << "姓名\t电话号码\t\tQQ\t\tEmail\t\t籍贯" << endl;
cout << current->name <<"\t"<< current->tel <<"\t"<< current->qq <<"\t"<< current->address <<"\t"<< current->email <<"\t"<< endl;
}
else
{
cout << "不存在该名人类" << endl;
}
}
void List::SearchByQQ(string qq)
{
Node* previous = nullptr;
Node* current;
for(current = head;
current && current->qq != qq;
previous = current, current = current->next);
if(current)
{
cout << "姓名\t电话号码\t\tQQ\t\tEmail\t\t籍贯" << endl;
cout << current->name <<"\t"<< current->tel <<"\t"<< current->qq <<"\t"<< current->address <<"\t"<< current->email <<"\t"<< endl;
}
else
{
cout << "不存在该名人类" << endl;
}
}
void List::SearchByTel(string tel)
{
Node* previous = nullptr;
Node* current;
for(current = head;
current && current->tel != tel;
previous = current, current = current->next);
if(current)
{
cout << "姓名\t电话号码\t\tQQ\t\tEmail\t\t籍贯" << endl;
cout << current->name <<"\t"<< current->tel <<"\t"<< current->qq <<"\t"<< current->address <<"\t"<< current->email <<"\t"<< endl;
}
else
{
cout << "不存在该名人类" << endl;
}
}
void List::ModifyByName(string name,string newtel,string newqq,string newemail,string newaddress)
{
Node* previous = nullptr;
Node* current;
for(current = head; current && current->name != name; previous = current,current = current->next);
if (current)
{
current->tel = newtel,current->qq = newqq,current->email = newemail,current->address = newaddress;
}
else
{
cout << "不存在该名人类" << endl;
}
}
void List::ModifyByQQ(string qq,string newname,string newtel,string newemail,string newaddress)
{
Node* previous = nullptr;
Node* current;
for(current = head; current && current->qq != qq; previous = current,current = current->next);
if (current)
{
current->name = newname,current->tel = newtel,current->email = newemail,current->address = newaddress;
}
else
{
cout << "不存在该名人类" << endl;
}
}
void List::ModifyByTel(string tel,string newname,string newqq,string newemail,string newaddress)
{
Node* previous = nullptr;
Node* current;
for(current = head; current && current->tel != tel; previous = current,current = current->next);
if (current)
{
current->name = newname,current->qq = newqq,current->email = newemail,current->address = newaddress;
}
else
{
cout << "不存在该名人类" << endl;
}
}
void List::Show()
{
cout << "姓名\t电话号码\t\tQQ\t\tEmail\t\t籍贯" << endl;
for(Node* current = head; current; current = current->next)
{
cout << current->name <<"\t"<< current->tel <<"\t"<< current->qq <<"\t"<< current->email <<"\t"<< current->address <<"\t"<< endl;
}
}
void menu()
{
printf("----------------通讯录管理系统--------------------\n");
printf("You can choose the following operations:\n");
printf("0.Exit system\n");
printf("1.Add\n");
printf("2.Browse\n");
printf("3.Delete\n");
printf("4.Modify\n");
printf("5.Query\n");
}
List l;
void keyDown()
{
string name, tel, qq, email, address, op;
Node* p = nullptr;
string newname, newtel, newqq, newemail, newaddress;
int choice = 0;
cin >> choice;
switch (choice)
{
case 0:
cout << "退出成功,感谢您的使用!";
system("pause");
exit(0);
break;
case 1:
cout << "---------【录入信息】---------\n";
cout << "请输入姓名,电话号码,QQ,Email,籍贯" << endl;
cin >> name >> tel >> qq >> email >> address;
l.Insert(name, tel, qq, email, address);
break;
case 2:
cout << "---------【浏览信息】---------\n";
l.Show();
break;
case 3: //这里需要可以用三种操作进行删除
cout << "---------【删除信息】---------\n";
cout << "请选择要删除的方式(姓名,电话,qq)" << endl;
cin >> op;
if (op == "姓名")
{
cout << "请输入需要删除的人的姓名" << endl;
cin >> name;
l.DeleteByName(name);
}
else if (op == "电话")
{
cout << "请输入需要删除的人的电话" << endl;
cin >> tel;
l.DeleteByTel(tel);
}
else if (op == "qq")
{
cout << "请输入需要删除的人的qq" << endl;
cin >> qq;
l.DeleteByQQ(qq);
}
else
{
cout << "输入错误,返回上一层" << endl;
}
break;
case 4: //这里同样也是三种操作
cout << "---------【修改信息】---------\n";
cout << "请选择要修改的方式(姓名,电话,qq)" << endl;
cin >> op;
if (op == "姓名")
{
cout << "请输入需要修改信息的人的姓名" <<endl;
cin >> name;
cout << "请输入修改后的人的QQ" << endl;
cin >> newqq;
cout << "请输入修改后的人的电话号码" << endl;
cin >> newtel;
cout << "请输入修改后的人的Email" << endl;
cin >> newemail;
cout << "请输入修改后的人的籍贯" << endl;
cin >>newaddress;
l.ModifyByName(name,newtel,newqq,newemail, newaddress);
}
else if (op == "电话")
{
cout << "请输入需要修改信息的人的电话号码" <<endl;
cin >> tel;
cout << "请输入修改后的人的姓名" << endl;
cin >> newname;
cout << "请输入修改后的人的QQ" << endl;
cin >> newqq;
cout << "请输入修改后的人的Email" << endl;
cin >> newemail;
cout << "请输入修改后的人的籍贯" << endl;
cin >>newaddress;
l.ModifyByTel(tel,newname,newqq,newemail, newaddress);
}
else if (op == "qq")
{
cout << "请输入需要修改信息的人的QQ" <<endl;
cin >> qq;
cout << "请输入修改后的人的姓名" << endl;
cin >> newname;
cout << "请输入修改后的人的电话" << endl;
cin >> newtel;
cout << "请输入修改后的人的Email" << endl;
cin >> newemail;
cout << "请输入修改后的人的籍贯" << endl;
cin >>newaddress;
l.ModifyByQQ(qq,newname,newtel,newemail, newaddress);
}
else
{
cout << "输入错误,返回上一层" << endl;
}
break;
case 5:
cout << "---------【查找信息】---------\n";
cout << "请选择要查找的方式(姓名,电话,qq)" << endl;
cin >> op;
if (op == "姓名")
{
cout << "请输入需要查找的人的姓名" << endl;
cin >> name;
l.SearchByName(name);
}
else if (op == "电话")
{
cout << "请输入需要查找的人的电话" << endl;
cin >> tel;
l.SearchByTel(tel);
}
else if (op == "qq")
{
cout << "请输入需要查找的人的qq" << endl;
cin >> qq;
l.SearchByQQ(qq);
}
else
{
cout << "输入错误,返回上一层" << endl;
}
break;
default:
cout << "选择错误,请重新输入" << endl;
system("pause");
break;
}
}
int main()
{
while(1)
{
menu();
keyDown();
system("pause");
system("cls");
}
return 0;
}
四、总结
怎么说呢,这个作业说难是真的不难,说简单也有点麻烦,起初全是因为我想用链表写系统(不要掩饰你只会用链表写系统的笨),然后就学习了下链表类的写法,感觉其实还是有很大的优化空间的,整个代码看下来也就三四个部分的复制粘贴而已,也没有多大难度,嗯....就这样吧
期待有dalao给蒟蒻指正