链表初识
概念:
链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。
一般的链表类型都是这样 前驱和后继分别指向的是数据和下一个的地址
实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:
- 单向、双向
- 带头、不带头
- 循环、非循环
无头链表
无头单向非循环链表:
结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多
增删查改
无论是什么功能首先前提条件就是创建结点。
SListNode* BuySListNode(SLTDateType x)
{
SListNode* node = (SListNode*)malloc(sizeof(SListNode));
node->data = x;//数据
node->next = NULL;//后继指向的地址
return node;
}
增(尾插)
void SListPushBack(SListNode** pplist, SLTDateType x)
{
SListNode* newnode = BuySListNode(x);//创建一个增加的结点
if (*pplist == NULL)//空链表
{
*pplist = newnode;//将创建结点给向头结点
}
else//不为空
{
SListNode* tail = *pplist;//找尾结点
while (tail->next != NULL)//找到尾结点尾结点最后指向NULL
{
tail = tail->next;//尾结点给前一个
}
tail->next = newnode;//再将原先指向尾结点指向插入的结点
}
}
删(尾删)
将尾部前一个的指向tail的结点指向NULL就将其删除了。
注释:
所以重要的删除后一个的时候要先保存原先的指向。
void SListPopBack(SListNode** pplist)
{
SListNode* prev = NULL;
SListNode* tail = *pplist;
// 1.空、只有一个节点
// 2.两个及以上的节点
if (tail == NULL || tail->next == NULL)//空或者一
{
free(tail);
*pplist = NULL;直接将头置NULLfree掉建立的指针让后续接着用
}
else
{
while (tail->next)//一个以上结点
{
prev = tail;//将tail的值给prev然后再对下一个结点遍历
tail = tail->next;
}//直到找到最后一个结点
free(tail);
tail = NULL;//将尾指NULL
prev->next = NULL;//将上一个保存的结点指向空
}
}
查改
SListNode* SListFind(SListNode* plist, SLTDateType x)
{
SListNode* cur = plist;//定义一个指针指向传进来的链表
while (cur)//找到数据
{
if (cur->data == x)//get it
return cur;//这里如果想要修改就将加入data赋值语句
cur = cur->next;//继续遍历链表
}
return NULL;//没有return空
}