手机通讯录

手机通讯录


一、目的

-掌握vector用法
-掌握链表的创建,插入,删除
-掌握哈希法的链地址法

二、实验内容与设计思想

1.顺序链表
函数相关伪代码

1.定义结构
2.制作菜单栏(switch)
3.添加的函数,一个一个添加在链表最末端,最后返回菜单
4.删除的函数,创建三个链表节点,分别表示当前节点,当前节点的前一个节点,当前节点的后一个节点,delete要删除节点,返回菜单
5.根据姓名查找的函数,从头开始遍历,直到找到,返回菜单
6.根据电话查找的函数,从头开始遍历,直到找到,返回菜单
7.显示所有人的函数,从头遍历,返回菜单
8.退出通讯录

函数代码

#include <iostream>
#include <string>
using namespace std;

struct Person
{
    string name;
    string phone;
    struct Person* next = NULL;
};

void AddPerson(Person* root);
Person* menue(int i);
void DeletePerson(Person* root);
void FindPersonname(Person* root);
void FindPersonphone(Person* root);
void ChangePerson(Person* root);
void AllPerson(Person* root);
Person* root = new Person;

Person* menue(int i)
{
    int s;
    cout << "欢迎使用通讯录管理系统\n";
    cout << "请选择接下来要做什么:\n1.添加联系人\n2.删除联系人\n3.通过姓名查找联系人\n4.通过电话查找联系人\n5.修改联系人\n6.显示所有联系人\n7.退出程序\n请输入对应的数字:" << endl;
    cin >> s;
    do{
        switch (s) {
        case 1:
            AddPerson(root);
            break;
        case 2:
            DeletePerson(root);
            break;
        case 3:
            FindPersonname(root);
            break;
        case 4:
            FindPersonphone(root);
            break;
        case 5:
            ChangePerson(root);
            break;
        case 6:
            AllPerson(root);
            break;
        case 7:
            cout << "退出程序";
            break;
        default:
            cout << "输入错误,请重新输入";
            break;
        }
    }while (s != 7);
        return root;
}

void AddPerson(Person* root) {
    Person* p = new Person;
    cout << "请输入姓名:";
    cin >> p->name;
    cout << "请输入电话:";
    cin >> p->phone;
    cout << "添加成功!" << endl;
    Person* temp = root;
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = p;

    menue(2);
}
void FindPersonname(Person* root1) {
    string name;
    Person* root = root1;
    cout << "请输入要查找的联系人姓名:";
    cin >> name;
    while (root != NULL) {
        if (root->name == name && root != NULL) {
            cout << "姓名:" << root->name << " 电话:" << root->phone << endl;
            cout << "查找成功!" << endl;
            break;
        }
        root = root->next;
    }
    if (root == NULL)
        cout << "查找失败!" << endl;
    menue(3);
}
void FindPersonphone(Person* root1) {
    string phone;
    Person* root2 = root1;
    cout << "请输入要查找的联系人电话:";
    cin >> phone;
    while (root2 != NULL) {
        if (root2->phone == phone) {
            cout << "姓名:" << root2->name << " 电话:" << root2->phone << endl;
            cout << "查找成功!" << endl;
            break;
        }
        root2 = root2->next;
    }
    if (root2 == NULL)
        cout << "查找失败!" << endl;
    menue(4);
}
void ChangePerson(Person* root1) {
    Person* root2 = root1;
    string name;
    cout << "请输入要修改的联系人姓名:";
    cin >> name;
    cout << "请输入新的电话:";
    string newPhone;
    cin >> newPhone;
    while (root2 != NULL) {
        if (root2->name == name) {
            root2->phone = newPhone;
            cout << "修改成功!" << endl;
            break;
        }
        root2 = root2->next;
    }
    if (root2 == NULL)
        cout << "修改失败!" << endl;
    menue(5);
}
void AllPerson(Person* root1) {
    Person* root2 = root1->next;
    cout << "所有联系人信息:" << endl;
    while (root2 != NULL) {
        cout << "姓名:" << root2->name << " 电话:" << root2->phone << endl;
        root2 = root2->next;
    }
    menue(6);
}
void DeletePerson(Person* root1) {
    string name;
    int k = 1;
    Person* root4 = root1;
    Person* root2 = root;
    Person* root3 = root;
    cout << "请输入要删除的联系人姓名:";
    cin >> name;
    while (root4 != NULL) {
        if (root4->name == name) {
            root2 = root4->next;
            delete root4;
            root3->next = root2;
            cout << "删除成功!" << endl;
            k = 0;
            break;
        }
        root3 = root4;
        root4 = root4->next;
    }
    if (k == 1)
        cout << "删除失败!" << endl;
    menue(7);
}

int main() {
    menue(1);
    while (root != NULL) {
        Person* temp = root;
        root = root->next;
        delete temp;
    }
    return 0;
}

2.哈希法(链地址法)
函数相关伪代码

1.定义结构
2.定义vector来存储列表头节点,使用名字的字符长度来存储,取其对于7的余数,来确定位置
3.制作菜单栏(switch)
4.先在主菜单上确定名字和电话和字符串长度,再到添加的函数,添加在m=name.length()%7的vector[m]的链表最末端,最后返回菜单
5.先在主菜单上确定名字和字符串长度,再到删除的函数,创建三个链表节点,分别表示当前节点,当前节点的前一个节点,当前节点的后一个节点,delete要删除节点,返回菜单
6.先在主菜单上确定名字和字符串长度,根据姓名查找的函数,从m=name.length()%7的vector[m]的头节点开始遍历,直到找到,返回菜单
7.显示所有人的函数,从头遍历,返回菜单
8.退出通讯录

函数代码
1.对名字长度取模

#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct Person
{
    string name;
    string phone;
	struct Person* next=NULL;
};
vector<Person*> contacts(7);
void AddPerson(int m,string name,string phone);
Person* menue(int i);
void DeletePerson(int m, string name);
void FindPersonname(int m,string name);
void ChangePerson(int m, string name, string newPhone);
void AllPerson();

Person* menue(int i)
{
    int s,m;
    string name, newPhone,phone;
    cout << "欢迎使用通讯录管理系统\n";
    cout << "请选择接下来要做什么:\n1.添加联系人\n2.删除联系人\n3.通过姓名查找联系人\n4.修改联系人\n5.显示所有联系人\n6.退出程序\n请输入对应的数字:" << endl;
    cin >> s;
    do{
    switch (s) {
    case 1:
        cout << "请输入姓名:";
        cin >> name;
        cout << "请输入电话:";
        cin >> phone;
		m= name.length() % 7;
        AddPerson(m,name,phone);
        break;
    case 2:
        cout << "请输入要删除的联系人姓名:";
        cin >> name;
		m = name.length() % 7;
        DeletePerson(m,name);
        break;
    case 3:
        cout << "请输入要查找的联系人姓名:";
        cin >> name;
		m = name.length() % 7;
        FindPersonname(m, name);
        break;
    case 4:
        cout << "请输入要修改的联系人姓名:";
        cin >> name;
        cout << "请输入新的电话:";
        cin >> newPhone;
		m = name.length() % 7;
        ChangePerson(m,name,newPhone);
        break;
    case 5:
        AllPerson();
        break;
    case 6:
        cout << "退出程序";
        break;
    default:
        cout << "输入错误,请重新输入";
        break;
    }
    }while (s != 6);
    return NULL;
}

void AddPerson(int m, string name,string phone) {
    Person* p = new Person;
	p->name = name;
	p->phone = phone;
    cout << "添加成功!" << endl;
    Person* temp = contacts[m];
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = p;
    menue(2);
}
void DeletePerson(int m, string name) {
    int k = 1;
    Person* root4 = contacts[m];
    Person* root2 = contacts[m];
    Person* root3 = contacts[m];
    while (root4 != NULL) {
        if (root4->name == name) {
            root2 = root4->next;
            delete root4;
            root3->next = root2;
            cout << "删除成功!" << endl;
            k = 0;
            break;
        }
        root3 = root4;
        root4 = root4->next;
    }
    if (k == 1)
        cout << "删除失败!" << endl;
    menue(6);
}
void FindPersonname(int m,string name) {
	Person* root = contacts[m];
	while (root != NULL) {
		if (root->name == name&&root!=NULL) {
			cout << "姓名:" << root->name << " 电话:" << root->phone << endl;
            cout << "查找成功!" << endl;
			break;
		}
		root = root->next;
	}
    if (root == NULL)
	cout << "查找失败!" << endl;
	menue(3);
}
void ChangePerson(int m,string name,string newPhone) {
    Person* root2 = contacts[m];
    while (root2 != NULL) {
        if (root2->name == name) {
			root2->phone = newPhone;
            cout << "修改成功!" << endl;
            break;
        }
        root2 = root2->next;
    }
	if (root2 == NULL)
	cout << "修改失败!" << endl;
	menue(4);
}
void AllPerson() {
    int i;
	cout << "所有联系人信息:" << endl;
    for (i = 0;i < 7;i++) {
		Person* root2 = contacts[i]->next;
        while (root2 != NULL) {
            cout << "姓名:" << root2->name << " 电话:" << root2->phone << endl;
            root2 = root2->next;
        }
    }
	menue(5);
}

int main() {
    int i;
    for (i = 0;i < 7;i++) {
		contacts[i] = new Person;
		contacts[i]->next = NULL;
    }
    menue(1);
    for (i = 0; i < 7;i++) {
        Person* root = contacts[i];
        while (root != NULL) {
            Person* temp = root;
            root = root->next;
            delete temp;
        }
    }
    return 0;
}

2.对A~Z取模,第一个字母必为字母

#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct Person
{
    string name;
    string phone;
    struct Person* next = NULL;
};
vector<Person*> contacts(26);
void AddPerson(int m, string name, string phone);
Person* menue(int i);
void DeletePerson(int m, string name);
void FindPersonname(int m, string name);
void ChangePerson(int m, string name, string newPhone);
void AllPerson();

Person* menue(int i)
{
    int s, m;
    string name, newPhone, phone;
    cout << "欢迎使用通讯录管理系统\n";
    cout << "请选择接下来要做什么:\n1.添加联系人\n2.删除联系人\n3.通过姓名查找联系人\n4.修改联系人\n5.显示所有联系人\n6.退出程序\n请输入对应的数字:" << endl;
    cin >> s;
    do {
        switch (s) {
        case 1:
            cout << "请输入姓名:";
            cin >> name;
            cout << "请输入电话:";
            cin >> phone;
            if (name.front() >= 'A' && name.front() <= 'Z') {
                m = (name.front() - 'A') % 26;
            }
            else if (name.front() >= 'a' && name.front() <= 'z') {
                m = (name.front() - 'a') % 26;
            }
            AddPerson(m, name, phone);
            break;
        case 2:
            cout << "请输入要删除的联系人姓名:";
            cin >> name;
            if (name.front() >= 'A' && name.front() <= 'Z') {
                m = (name.front() - 'A') % 26;
            }
            else if (name.front() >= 'a' && name.front() <= 'z') {
                m = (name.front() - 'a') % 26;
            }
            DeletePerson(m, name);
            break;
        case 3:
            cout << "请输入要查找的联系人姓名:";
            cin >> name;
            if (name.front() >= 'A' && name.front() <= 'Z') {
                m = (name.front() - 'A') % 26;
            }
            else if (name.front() >= 'a' && name.front() <= 'z') {
                m = (name.front() - 'a') % 26;
            }
            FindPersonname(m, name);
            break;
        case 4:
            cout << "请输入要修改的联系人姓名:";
            cin >> name;
            cout << "请输入新的电话:";
            cin >> newPhone;
            if (name.front() >= 'A' && name.front() <= 'Z') {
                m = (name.front() - 'A') % 26;
            }
            else if (name.front() >= 'a' && name.front() <= 'z') {
                m = (name.front() - 'a') % 26;
            }
            ChangePerson(m, name, newPhone);
            break;
        case 5:
            AllPerson();
            break;
        case 6:
            cout << "退出程序";
            break;
        default:
            cout << "输入错误,请重新输入";
            break;
        }
    } while (s != 6);
    return NULL;
}

void AddPerson(int m, string name, string phone) {
    Person* p = new Person;
    p->name = name;
    p->phone = phone;
    cout << "添加成功!" << endl;
    Person* temp = contacts[m];
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = p;
    menue(2);
}
void DeletePerson(int m, string name) {
    int k = 1;
    Person* root4 = contacts[m];
    Person* root2 = contacts[m];
    Person* root3 = contacts[m];
    while (root4 != NULL) {
        if (root4->name == name) {
            root2 = root4->next;
            delete root4;
            root3->next = root2;
            cout << "删除成功!" << endl;
            k = 0;
            break;
        }
        root3 = root4;
        root4 = root4->next;
    }
    if (k == 1)
        cout << "删除失败!" << endl;
    menue(6);
}
void FindPersonname(int m, string name) {
    Person* root = contacts[m];
    while (root != NULL) {
        if (root->name == name && root != NULL) {
            cout << "姓名:" << root->name << " 电话:" << root->phone << endl;
            cout << "查找成功!" << endl;
            break;
        }
        root = root->next;
    }
    if (root == NULL)
        cout << "查找失败!" << endl;
    menue(3);
}
void ChangePerson(int m, string name, string newPhone) {
    Person* root2 = contacts[m];
    while (root2 != NULL) {
        if (root2->name == name) {
            root2->phone = newPhone;
            cout << "修改成功!" << endl;
            break;
        }
        root2 = root2->next;
    }
    if (root2 == NULL)
        cout << "修改失败!" << endl;
    menue(4);
}
void AllPerson() {
    int i;
    cout << "所有联系人信息:" << endl;
    for (i = 0;i < 26;i++) {
        Person* root2 = contacts[i]->next;
        while (root2 != NULL) {
            cout << "姓名:" << root2->name << " 电话:" << root2->phone << endl;
            root2 = root2->next;
        }
    }
    menue(5);
}

int main() {
    int i;
    for (i = 0;i < 26;i++) {
        contacts[i] = new Person;
        contacts[i]->next = NULL;
    }
    menue(1);
    for (i = 0; i < 26;i++) {
        Person* root = contacts[i];
        while (root != NULL) {
            Person* temp = root;
            root = root->next;
            delete temp;
        }
    }
    return 0;
}

三、实验使用环境

以下请根据实际情况编写

  • 操作系统:Windows 11专业版
  • 编程语言:C++
  • 开发工具:[Visual Studio 2022]

四、实验步骤和调试过程

手机通讯录

1.顺序链表
本机运行截图




2.哈希法
本机运行截图



五、实验小结

遇到的问题及解决方法:

  1. 问题:创建的链表未正确处理,被覆盖
  • 解决方法:优化代码,修改链表的传递方法

实验体会和收获:

哈希法(链地址法)平均情况下操作时间复杂度为 O((n+1)/2),但最坏情况下同样是 O(n),这里的n指在相同m下有多少个链表,这个链表节点数会小于等于总链表节点数,空间复杂度为O(n),这里的n会大于等于总链表节点数。顺序链表法每个函数所遍历的时间复杂度都为O(n),空间复杂度为O(n),这里的n是总链表节点数。综上所述,在平均情况下,哈希法(链地址法)在查找、插入和删除操作上的性能要优于链表法。

posted @ 2025-04-20 16:14  穗和  阅读(37)  评论(0)    收藏  举报