基本知识点
注:数据结构系列将持续更新,欢迎交流讨论…
- 单向链表是一种线性结构
- 优点:作数据的删除、插入简单;缺点:数据查找慢
- 组成:数据域、后继节点的一个指针域;
- 单向链表,后继指针指向下一个结点
- 学数据结构的建议:学习每种结构的时候,首先得清除它的结构,所以自己首先要清楚大概的结构,自己画一画;文中我会展示出部分图片以供参考。
基本结构示意图
一般实现步骤
- 初始化结点参数/创建结点;
- 链接每个结点,让这些结点成为一个逻辑上相连接的链表;
- 注意点:指针的先后指向要捋清楚,谁先指,谁后指;
- 建议:学编程就是学的一种思维,有的问题可以不必深究;
简单的代码实现链表逻辑
typedef struct node//用typedef就可以在后面起别名
{
int num;
struct node* next;
}*p_node;//别名
void testList()
{
node data_1 = { 1,nullptr };
node data_2 = { 2,nullptr };
node data_3 = { 3,nullptr };
node data_4 = { 4.nullptr };
data_1.next = &data_2;
data_2.next = &data_3;
data_3.next = data_4;
node* pMove = &data_1;
while (pMove != nullptr)
{
cout << pMove->num << " ";
pMove = pMove->next;
}
- 上图展示的就是基本操作,创建结点和链接,打印,接下来我们只需要用函数将他封装一下,简单的实现一下增删改查的功能,就算是实现好了一个最基本的单向链表;
封装初始化结点函数
node* initnode(int value)
{
p_node newnode = new node;
newnode->num = value;
newnode->next = nullptr;
return newnode;
}
头插法插入节点
void insertHead(node* p_head, node* data)
{
data->next = p_head->next;
p_head->next = data;
}
插入过程示意图
尾插法
void insertTail(node* p_tail, p_node data)
{
data->next = p_tail->next;
p_tail->next = data;
}
插入过程示意图
查找和修改数据
(这个没什么好说的,看代码)
bool search(p_node pHead, int target, int value)
{
p_node pMove = pHead;
while (pMove != nullptr)
{
if (pMove->num == target)
{
pMove->num = value;
return true;
}
pMove = pMove->next;
}
return false;
}
删除结点
- 删除一个结点需要两个结点,一个指向当前结点,一个指向当前结点左侧,这样的目的是为了作结点删除时方便结点直接的链接;
- 删除过程:左侧结点断开当前结点的链接,去链接当前结点的右侧结点,如图所示:
bool deleteNode(p_node pHead,int target)
{
p_node pMove = pHead;
p_node pLight = pHead;
while (pMove != nullptr)
{
if (pMove->num == target)
{
pLight->next = pMove->next;
delete pMove;
pMove = nullptr;
return true;
}
pLight = pMove;
pMove = pMove->next;
}
return false;
}
删除过程指针移动示意图
注意点:要始终保持pLight结点在pMove结点的左侧,这样删除的时候好作结点之间的链接。
结语
数据结构的内容将持续更新,如文中有误还请不吝赐教;欢迎评论区留言或私信讨论。