【練手小專案】簡易通訊錄:單連結串列實現

codels發表於2024-07-19

簡易通訊錄:單連結串列實現

結構描述:

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

class PeoNode {
private:
    string name;
    string sex;
    int age;
    string tele;
    string addr;

    PeoNode * next;

    //Provide Contact access;
    friend class Contact;
};

class Contact {
public:
    //初始化通訊錄資訊
    void initContact();
    //判空
    bool isEmpty();
    //新增聯絡人
    void addPeople();
    //列印通訊錄資訊
    void printContact();
    //根據聯絡人的姓名刪除聯絡人
    void deleteByName(string & name);
    //根據姓名查詢聯絡人
    PeoNode * searchByName(string & name);
    //根據姓名修改聯絡人的資訊
    void modifyByName(string & name);
    //分配節點
    PeoNode * buyNode();
    //銷燬
    void makeEmpty();
private:
    PeoNode * head;
};

初始化通訊錄

把連結串列的頭指標置空:

void Contact::init() {
    head = nullptr;
}

新增聯絡人

使用頭插法新增聯絡人至連結串列中:

void Contact::addPeople() {
    PeoNode * newNode = buyNode();
    newNode->next = head;
    head = newNode;
}

分配節點

根據使用者輸入建立一個聯絡人節點,並返回節點。

PeoNode * Contact::buyNode() {
    //分配節點並判斷是否成功
    PeoNode * newNode = new PeoNode();
    if (newNode == nullptr) {
        cout << "New Failed!\n";
        exit(-1);
    }
    
    //輸入資訊
    cout << "Please enter name:> "; getline(cin, newNode->name);
    cout << "Please enter sex:> "; getline(cin, newNode->sex);
    //cin.ignore()方法忽略掉在讀取整數後可能殘留在輸入緩衝區中的換行符
    cout << "Please enter age:> "; cin >> newNode->age; cin.ignore();
    cout << "Please enter telephone:> "; getline(cin, newNode->tele);
    cout << "Please enter address:> "; getline(cin, newNode->addr);
	
    newNode->next = nullptr;
    
    return newNode;
}

列印通訊錄

  • 表空:不允許操作

  • 非空:遍歷並列印每一個元素

void Contact::printContact() {
    if (isEmpty()) {
        cout << "List Is Empty!\n";
        exit(-1);
    }
    
    //表頭
    cout << "name" << "\t"
         << "sex" << "\t"
         << "age" << "\t"
         << "tele" << "\t"
         << "addr" << "\n";
    PeoNode * cur = head;
    while (cur != nullptr) {
        cout << cur->name << "\t"
             << cur->sex << "\t"
             << cur->age << "\t"
             << cur->tele << "\t"
             << cur->addr << "\n";
        cur = cur->next;
    }
}

查詢聯絡人

根據聯絡人的名字查詢。

  • 表空:報錯
  • 非空:遍歷查詢,找到第一個名字匹配的,並返回節點指標,若到表尾還沒有找到,則聯絡人不存在
PeoNode * Contact::searchByName(string & name) {
    if (isEmpty()) {
        cout << "List Is Empty!\n";
        exit(-1);
    }
    
    PeoNode * cur = head;
    while (cur != nullptr) {
        if (cur->name == name) {
            return cur;
        }
        //向後遍歷
        cur = cur->next;
    }
    
    //沒找到返回nullptr
    return nullptr;
}

刪除聯絡人

  1. 根據名字查詢
  2. 找到:刪除
  3. 找不到:報告不存在
void Contact::deleteByName(string & name) {
    PeoNode * ret = searchByName(name);
    if (ret == nullptr) {
        cout << "People is Not Exist!\n";
        exit(-1);
    }

    //調整連結串列的關係
    PeoNode * cur = head;
    while (cur->next != ret) {
        cur = cur->next;
    }
    cur->next = ret->next;
    
    //釋放節點
    delete ret;
    ret = nullptr;
}

修改聯絡人資訊

  1. 根據名字查詢
  2. 查詢成功:修改
  3. 查詢失敗:返回錯誤
void Contact::modifyByName(string & name) {
    PeoNode * ret = searchByName(name);
    if (ret == nullptr) {
        cout << "Search Failed!\n";
        exit(-1);
    }
    
        //輸入資訊
    cout << "Please enter name:> "; getline(cin, ret->name);
    cout << "Please enter sex:> "; getline(cin, ret->sex);
    //cin.ignore()方法忽略掉在讀取整數後可能殘留在輸入緩衝區中的換行符
    cout << "Please enter age:> "; cin >> ret->age; cin.ignore();
    cout << "Please enter telephone:> "; getline(cin, ret->tele);
    cout << "Please enter address:> "; getline(cin, ret->addr);
}

銷燬

  • 表空:返回錯誤
  • 非空:一直頭刪,直至表空
void Contact::makeEmpty() {
    if (isEmpty()) {
        cout << "List Is Empty!\n";
        exit(-1);
    }
    
	while (!isEmpty()) {
        cout << head->name;
        //頭刪
        PeoNode * tmp = head;
        head = head->next;
        free(tmp);
        tmp = nullptr;
        
        cout << "has been poped!\n";
    }
    
    cout << "Make Empty Successfully!\n";
}

綜上

Contact.hpp

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

class PeoNode {
private:
    string name;
    string sex;
    int age;
    string tele;
    string addr;

    PeoNode * next;

    //Provide Contact access;
    friend class Contact;
};

class Contact {
public:
    //初始化通訊錄資訊
    void initContact();
    //判空
    bool isEmpty();
    //新增聯絡人
    void addPeople();
    //列印通訊錄資訊
    void printContact();
    //根據聯絡人的姓名刪除聯絡人
    void deleteByName(string & name);
    //根據姓名查詢聯絡人
    PeoNode * searchByName(string & name);
    //根據姓名修改聯絡人的資訊
    void modifyByName(string & name);
    //分配節點
    PeoNode * buyNode();
    //銷燬
    void makeEmpty();
private:
    PeoNode * head;
};

Contact.cpp

#include "Contact.hpp"

void Contact::initContact() {
    head = nullptr;
}

bool Contact::isEmpty() {
    return head == nullptr;
}

void Contact::addPeople() {
    PeoNode * newNode = buyNode();
    newNode->next = head;
    head = newNode;
}

PeoNode * Contact::buyNode() {
    //分配節點並判斷是否成功
    PeoNode * newNode = new PeoNode();
    if (newNode == nullptr) {
        cout << "New Failed!\n";
        exit(-1);
    }
    
    //輸入資訊
    cout << "Please enter name:> "; getline(cin, newNode->name);
    cout << "Please enter sex:> "; getline(cin, newNode->sex);
    //cin.ignore()方法忽略掉在讀取整數後可能殘留在輸入緩衝區中的換行符
    cout << "Please enter age:> "; cin >> newNode->age; cin.ignore();
    cout << "Please enter telephone:> "; getline(cin, newNode->tele);
    cout << "Please enter address:> "; getline(cin, newNode->addr);
	
    newNode->next = nullptr;
    
    return newNode;
}

void Contact::printContact() {
    if (isEmpty()) {
        cout << "List Is Empty!\n";
        exit(-1);
    }
    
    //表頭
    cout << "name" << "\t"
         << "sex" << "\t"
         << "age" << "\t"
         << "tele" << "\t"
         << "addr" << "\n";
    PeoNode * cur = head;
    while (cur != nullptr) {
        cout << cur->name << "\t"
             << cur->sex << "\t"
             << cur->age << "\t"
             << cur->tele << "\t"
             << cur->addr << "\n";
        cur = cur->next;
    }
}

PeoNode * Contact::searchByName(string & name) {
    if (isEmpty()) {
        cout << "List Is Empty!\n";
        exit(-1);
    }
    
    PeoNode * cur = head;
    while (cur != nullptr) {
        if (cur->name == name) {
            return cur;
        }
        //向後遍歷
        cur = cur->next;
    }
    
    //沒找到返回nullptr
    return nullptr;
}

void Contact::deleteByName(string & name) {
    PeoNode * ret = searchByName(name);
    if (ret == nullptr) {
        cout << "People is Not Exist!\n";
        exit(-1);
    }

    //調整連結串列的關係
    PeoNode * cur = head;
    while (cur->next != ret) {
        cur = cur->next;
    }
    cur->next = ret->next;
    
    //釋放節點
    delete ret;
    ret = nullptr;
}

void Contact::modifyByName(string & name) {
    PeoNode * ret = searchByName(name);
    if (ret == nullptr) {
        cout << "Search Failed!\n";
        exit(-1);
    }
    
        //輸入資訊
    cout << "Please enter name:> "; getline(cin, ret->name);
    cout << "Please enter sex:> "; getline(cin, ret->sex);
    //cin.ignore()方法忽略掉在讀取整數後可能殘留在輸入緩衝區中的換行符
    cout << "Please enter age:> "; cin >> ret->age; cin.ignore();
    cout << "Please enter telephone:> "; getline(cin, ret->tele);
    cout << "Please enter address:> "; getline(cin, ret->addr);
}

void Contact::makeEmpty() {
    if (isEmpty()) {
        cout << "List Is Empty!\n";
        exit(-1);
    }
    
	while (!isEmpty()) {
        cout << head->name;
        //頭刪
        PeoNode * tmp = head;
        head = head->next;
        free(tmp);
        tmp = nullptr;
        
        cout << "has been poped!\n";
    }
    
    cout << "Make Empty Successfully!\n";
}

踩坑

C++處理字串輸入用 std::getline() 方法

C++中 new 關鍵字為物件分配空間,並返回該物件的指標。

相關文章