节点关系
node.h
#pragma once class MM; class Node{ public: Node(); Node(MM *data); Node(MM *data,Node* next); Node*& getNext(); //返回指针的引用,用于访问它里面的指针 MM*& getData(); //提供公有接口,用于访问它里面的数据 protected: MM *data; Node* next; };
node.cpp
.h要避免头文件包含(避免头文件的重复包含)---- 在.cpp中包含头文件即可
头插法实现数据插入---新插入的数据在最前面
#include "node.h" //用到了Node节点,需要包含头文件node.h #include "mm.h" Node::Node() { this->next = nullptr;//无参构造函数 直接把指针置为空 } Node::Node(MM* data) { this->data = data; //把数据做初始化,再把指针置为空 或 统一采用初始化参数列表的方式 this->next = nullptr; } Node::Node(MM* data, Node* next) { this->data = data; this->next = next; } Node*& Node::getNext() { return next; } MM*& Node::getData() { // TODO: 在此处插入 return 语句 return data; }
实现链表增删改查
list.h
#pragma once #include "mm.h" #include "node.h" //无头链表:表头存数据(这里实现的是有头链表 *** 作) //有头链表:表头不存数据 class list { public: list(); void insertList(MM* data); //采用头插法插入数据 void printList(); //打印链表中的数据 void deleteAppoin(string posData); //删除链表中的数据,根据姓名做删除 Node* searchByData(string posData); //查找链表中的数据,根据姓名做查找 void saveListToFile(const char* fileName); //文件 *** 作,把链表的数据流到文件中 void readFileToList(const char* fileName); //把文件的数据流到链表中 protected: Node* headNode; int curSize; //当前节点个数 };
list.cpp
删除表头,要改变表头的指向 第一个节点是要删除的节点要 单独处理
处理删除表头的情况:
1. 记录当前节点的(表头)下一个节点 2. 释放表头
//删除的是表头 Node* nextNode = curNode->getNext(); delete headNode; headNode = nextNode; this->curSize--; //删除成功改变size
处理删除链表中某个数据的情况:
//删除链表中的数据 preNode->getNext() = curNode->getNext(); delete curNode; curNode = nullptr; this->curSize--; //删除成功改变size
#include "list.h" #includeusing namespace std; list::list() { this->headNode = nullptr; this->curSize = 0; } //头插法 void list::insertList(MM* data) { //表头插入 headNode = new Node(data, headNode); this->curSize++; } //打印链表 void list::printList() { Node* pmove = headNode; cout << "name" << "t" << "age" << "t" << "tel" << "t" << "sex" << endl; while (pmove != nullptr) { //cout << pmove->getData() << endl; pmove->getData()->printMM(); pmove = pmove->getNext(); } } //删除链表 void list::deleteAppoin(string posData) { Node* preNode = headNode; Node* curNode = headNode; while (curNode!=nullptr&&curNode->getData()->getName() != posData) { preNode = curNode; curNode = curNode->getNext(); } if (curNode == nullptr) //如果链表为空,说明没找到 { cout << "删除失败!" << endl; } else if (curNode == preNode) //删除的节点是第一个节点,代表删除表头 { Node* nextNode = curNode->getNext(); delete headNode; headNode = nextNode; this->curSize--; } else { preNode->getNext() = curNode->getNext(); delete curNode; curNode = nullptr; this->curSize--; //删除成功改变size } } //查找链表中数据 Node* list::searchByData(string posData) { Node* pmove = headNode; while (pmove!=nullptr&&pmove->getData()->getName() != posData) { pmove = pmove->getNext(); } return pmove; } //文件 *** 作---从链表流入文件 void list::saveListToFile(const char* fileName) { fstream save(fileName, ios::out); Node* pmove = headNode; while (pmove != nullptr) { pmove->getData()->saveFile(save); pmove = pmove->getNext(); } save.close(); } //文件 *** 作---从文件流入链表 void list::readFileToList(const char* fileName) { fstream read(fileName, ios::in); while (1) { MM* mm = new MM; mm->readFile(read); if (read.eof()) break; insertList(mm); } read.close(); }
代码解析
文件 *** 作解析:
~所有数据存在链表中,对链表做封装文件 *** 作
~代码中做了数据的修改的地方,就要做一下文件的保存 *** 作---修改成功后、插入、删除
pList->saveListToFile("1.txt");
//文件 *** 作---从链表流入文件 写 void list::saveListToFile(const char* fileName) { fstream save(fileName, ios::out); Node* pmove = headNode; while (pmove != nullptr) { pmove->getData()->saveFile(save); //直接调用saveFile() pmove = pmove->getNext(); } save.close(); } //文件 *** 作---从文件流入链表 读 void list::readFileToList(const char* fileName) { fstream read(fileName, ios::in); while (1) { MM* mm = new MM; //因为存的是指针,所以每个数据都要new一个对象出来,要有无参构造函数 mm->readFile(read);//把数据读到链表中去 if (read.eof()) //最后一个读取不应该把数据读到链表中(多读了一次),否则会有乱码 break; insertList(mm); //把对象存到链表中去 } read.close(); }
测试链表的代码
int main() { list myList; //或者new一个对象出来 //插入3个数据 for(int i=0;i<3;i++){ myList.insert[i];//需要手动写析构函数 } myList.printlist(); //打印数据 }
mm.h---通讯录中包含的人物数据 单独描述成一个类
// 提供一些方法能够打印对象,能够打印数据
注意:
需要改链表存储数据的类型---管理的是MM类的数据
链表的删除、查找 由(通过数据做查找)改为 通过姓名做删除、查找
#pragma once class MM; class Node{ public: Node(); Node(MM *data); Node(MM *data,Node* next); Node*& getNext(); MM*& getData(); protected: MM *data; //如果用MM data需要包含头文件#include "mm.h",否则会报错 Node* next; }; //用指针MM* 不会报错, 指针只是声明一下,创建对象要已经存在,对象要有创建的过程
#pragma once #include#include #include using namespace std; class MM { public: MM(string name, int age, string tel, string sex); MM(); void printMM(); void saveFile(fstream& file); //把链表中的数据存到文件中--->流进去 void readFile(fstream& file); //读取文件的数据到链表--->流出来 string& getName(); int& getAge(); string& getTel(); string& getSex(); protected: string name; //通讯录的数据 int age; string tel; string sex; };
mm.cpp
#include "mm.h" MM::MM(string name, int age, string tel, string sex):name(name),age(age),tel(tel),sex(sex) { } MM::MM() { } void MM::printMM() { cout << name << "t" << age << "t" << tel << "t" << sex << endl; } void MM::saveFile(fstream& file) //提供保存数据的接口 { file << name << " " << age << " " << tel << " " << sex << endl; //直接把数据流到文件中 } void MM::readFile(fstream& file) { file >> name >> age >> tel >> sex; //分别流到name,age中,流出来忽视空格 } string& MM::getName() { return name; } int& MM::getAge() { // TODO: 在此处插入 return 语句 return age; } string& MM::getTel() { // TODO: 在此处插入 return 语句 return tel; } string& MM::getSex() { // TODO: 在此处插入 return 语句 return sex; }
MMSystem.h---实现通讯录人物增删改查功能的函数
#pragma once #include "list.h" class MMSystem { public: MMSystem(); void MakeMenu(); //菜单 void KeyDown(); //交互处理 void insertMM(); //插入数据(查找数据、删除数据也可以封装成函数) list*& getPList(); //提供接口访问属性pList protected: list* pList; };
在当前文件夹中新建一个1.txt 文本文档---用于处理链表流出来的数据 和 把数据流到链表中
MMSystem.cpp
#include "MMsystem.h" MMSystem::MMSystem():pList(new list) //类的组合:以另一个对象为数据成员 { pList->readFileToList("1.txt"); //对象创建完后要把存在 1.txt 中的数据加载到链表中 } void MMSystem::MakeMenu() { cout << "----------------【通讯录】------------------" << endl; cout << "tt0.退出系统" << endl; cout << "tt1.插入数据" << endl; cout << "tt2.删除数据" << endl; cout << "tt3.查找数据" << endl; cout << "tt4.修改数据" << endl; cout << "tt5.浏览数据" << endl; cout << "--------------------------------------------" << endl; } void MMSystem::KeyDown() { int userKey = 0; //new对象准备的变量 string name; Node* result; //准备一个指针变量,因为返回的是一个指针变量 cin >> userKey; switch (userKey) { case 0: exit(0); break; case 1: this->insertMM(); pList->saveListToFile("1.txt"); break; case 2: cout << "请输入需要删除的姓名:"; //这里可以封装成函数处理,类似 insertMM(); cin >> name; pList->deleteAppoin(name); pList->saveListToFile("1.txt"); break; case 3: cout << "请输入需要查找的姓名:"; cin >> name; result = pList->searchByData(name); if (result == nullptr) { cout << "查无此人!" << endl; } else { cout << "查找信息如下:" << endl; result->getData()->printMM(); } break; case 4: cout << "请输入要修改的姓名:"; cin >> name; result = pList->searchByData(name); //通过姓名做查找 if (result == nullptr) { cout << "查无此人!无法修改" << endl; } else { cout << "请输入修改的信息:" << endl; cin >> result->getData()->getName() >> result->getData()->getAge() >> result->getData()->getTel() >> result->getData()->getSex(); cout << "修改成功" << endl; pList->saveListToFile("1.txt"); } break; case 5: pList->printList(); break; } } void MMSystem::insertMM() //new对象准备的变量 { string name; int age; string tel; //电话 string sex; //性别 cout << "请分别输入姓名、年龄、电话号码、性别:" << endl; cin >> name >> age >> tel >> sex; pList->insertList(new MM(name, age, tel, sex)); } list*& MMSystem::getPList() { // TODO: 在此处插入 return 语句 return pList; }
c++管理系统.cpp---主函数部分
#include "MMsystem.h" #includeint main() { MMSystem* pSystem = new MMSystem; while (1) { pSystem->MakeMenu(); pSystem->KeyDown(); system("pause"); system("cls"); } return 0; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)