基本知识点
注:数据结构系列将持续更新,欢迎交流讨论…
- 有头链表和单项链表差不多是一种线性结构,只是比单项链表多一个不存储数据的、用来操作链表的头节点;
- 优点:作数据的删除、插入简单;缺点:数据查找慢
- 组成:数据域、头节点、尾结点、后继节点的一个指针域;
- 有头链表,后继指针指向下一个结点;
- 学数据结构的建议:学习每种结构的时候,首先得清除它的结构,所以自己首先要清楚大概的结构,自己画一画;文中我会展示出部分图片以供参考。
基本结构



注:这三张图分别是有头链表的初始状态(只有头节点和尾结点)、基本模型、插入时后进行的操作
一般实现步骤
- 构建数据模型;(以什么方式实现链表,结构体、类等)
- 初始化头节点,尾结点;
- 初始化结点参数/创建结点;
- 用头结点或尾结点来操作链接每个结点,让这些结点成为一个逻辑上相连接的链表;
- 注意点:指针的先后指向要捋清楚,谁先指,谁后指;
- 建议:学编程就是学的一种思维,有的问题可以不必深究;
List.h文件代码
#pragma once
typedef struct DATA
{
int number;
int score[3];
DATA* next;
}Data, * p_Data;
class System
{
public:
System();
~System();
p_Data initData();
p_Data createData(int number, int score_1, int score_2, int score_3);
void insertHData(p_Data data);
void insertTData(p_Data data);
bool deleteData(int delNum);
bool changeData(int oldNum,int newNum);
bool searchData(int seaNum);
void printData();
int Size();
protected:
p_Data m_head;
p_Data m_tail;
int m_curSize;
};
List.cpp文件
#include "List.h"
#include <iostream>
using namespace std;
System::System()
{
this->m_head = this->initData();
this->m_tail = this->initData();
m_head->next = m_tail;
this->m_curSize = 0;
}
System::~System()
{
if (m_head != nullptr)
{
delete m_head;
m_head = nullptr;
}
if (m_tail != nullptr)
{
delete m_tail;
m_tail = nullptr;
}
this->m_curSize = 0;
}
p_Data System::initData()
{
p_Data data = new Data;
data->next = nullptr;
data->number = 0;
for (int i = 0; i < 3; i++)
{
data->score[i] = 0;
}
return data;
}
p_Data System::createData(int number, int score_1, int score_2, int score_3)
{
p_Data newData = initData();
newData->number = number;
newData->score[0] = score_1;
newData->score[1] = score_2;
newData->score[2] = score_3;
return newData;
}
void System::insertHData(p_Data data)
{
data->next = this->m_head->next;
m_head->next = data;
this->m_curSize++;
}
void System::insertTData(p_Data data)
{
p_Data pMove = m_head;
p_Data pLight = m_head;
while (pMove != m_tail)
{
pLight = pMove;
pMove = pMove->next;
}
data->next = pLight->next;
pLight->next = data;
this->m_curSize++;
}
bool System::deleteData(int delNum)
{
p_Data pMove = m_head->next;
p_Data pLight = m_head;
while (pMove != m_tail)
{
if (pMove->number == delNum)
{
pLight->next = pMove->next;
delete pMove;
pMove = nullptr;
m_curSize--;
return true;
}
pLight = pMove;
pMove = pMove->next;
}
return false;
}
bool System::changeData(int oldNum,int newNum)
{
p_Data pMove = m_head->next;
while (pMove != m_tail)
{
if (pMove->number == oldNum)
{
pMove->number = newNum;
return true;
}
pMove = pMove->next;
}
return false;
}
bool System::searchData(int seaNum)
{
p_Data pMove = m_head->next;
while (pMove != m_tail)
{
if (pMove->number == seaNum)
{
return true;
}
pMove = pMove->next;
}
return false;
}
void System::printData()
{
p_Data pMove = this->m_head;
while (pMove->next != m_tail)
{
pMove = pMove->next;
cout << pMove->number << "\t";
for (int i = 0; i < 3; i++)
{
cout << pMove->score[i] << "\t";
}
cout << endl;
}
}
int System::Size()
{
return this->m_curSize;
}
Main.cpp测试代码
#include <iostream>
#include "List.h"
using namespace std;
int main()
{
System sys;
p_Data data_1 = sys.createData(192, 89, 90, 89);
p_Data data_2 = sys.createData(193, 79, 79, 79);
p_Data data_3 = sys.createData(194, 90, 99, 85);
p_Data data_4 = sys.createData(195, 85, 85, 85);
sys.insertHData(data_1);
sys.insertHData(data_2);
sys.insertTData(data_3);
sys.insertTData(data_4);
cout << "链表含有 " << sys.Size() << " 个数据..." << endl;
sys.printData();
cout << endl;
sys.deleteData(195);
sys.printData();
cout << endl;
sys.changeData(192, 198);
sys.printData();
if (sys.searchData(192))
{
cout << "含有该数据..." << endl;
}
else
{
cout << "没有该数据..." << endl;
}
return 0;
}
尾插法指针的移动

结语
这些内容是我平时的所学知识的理解,数据结构的内容将持续更新,如文中有误还请不吝赐教;欢迎评论区留言或私信讨论。