用链表类实现通讯录管理系统

我是周日下午开始写的,本来觉得这个作业很简单,老师只是说用class类写一个通讯录管理系统,没指明具体用啥数据结构,俺又不会用对象数组(明明ppt上有,只是偷懒不想看),所以就打算用类实现链表来完成这个系统。

很快啊,用了不到一个小时就写了个大框架,然后发现,tnnd我这个链表只能存一个人(当场气晕),事实上都不能叫链表了。然后啊,就去寻求万能的网友们的帮助,于是就发现了这篇大神写的博客,这里给下地址(16条消息) c++数据结构与算法(10)——链表(使用class实现)_北顾+的博客-CSDN博客_链表类

侵删(蒟蒻瑟瑟发抖)

namo接下来就来看看俺的bug系统8

目录

一、Node类的创建

二、List类的创建(重要)

三、完整代码

四、总结


一、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给蒟蒻指正

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值