单链表的基本操作
Posted 王不患吖吖吖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单链表的基本操作相关的知识,希望对你有一定的参考价值。
单链表的基本介绍
单链表是顺序表的一种,顺序表指的是可以线性排列,具有同种元素的有限序列。比如数组是顺序表的一种,它的空间上是连续的,逻辑上也是连续的。
而链表是由指针进行连接的,空间上是不连续的,逻辑上是连续的。
链表与数组的区别
对于链表它是不支持随机访问的,因为它必须知道它的地址,要寻找上一个节点,而数组可以随机访问
在插入元素上,数组上可能要搬运元素,但是链表却可以任意插入,时间复杂度较高。
如果插入了许多元素,链表不需要扩容,而数组需要
对于元素频繁访问,数组会更好一点,对于任意位置插入和删除,链表会更好
顺序表的缓存利用率更高
链表的基本操作
前置
typedef int SLDataType ;
typedef struct SListNode
SLDataType data;
struct SListNode* next;
SL;
链表的创建
SL* BuySListNode(SLDataType x)
SL* NewNode = (SL*)malloc(sizeof(SL));
if (NewNode == NULL)
exit(-1);
NewNode->data = x;
NewNode->next = NULL;
return NewNode;
malloc一个节点,把内容传进去
链表的尾插
先找到尾,把新节点连接上去,
void SListPushBack(SL** pphead,SLDataType x)
SL* NewNode = BuySListNode(x);
if (*pphead == NULL)
*pphead = NewNode;
//当头节点为空的时候
else
SL* tail = *pphead;
while (tail->next != NULL)
tail = tail->next;
tail->next = NewNode;//tail->next为空
//找到尾节点尾节点的后面连接上新节点
链表的头插
我们是改变了头指针,所以传入指针的地址,所以是二重指针
void SListPushFront(SL** pphead, SLDataType x)
SL* NewNode = BuySListNode(x);
NewNode->next = *pphead;
*pphead = NewNode;
//让新节点连接上起始节点,再让新节点作为起始节点
链表的尾删
注意先判断是不是只有一个节点,如果是那么直接free,而且找到tail的next,再free,然后再置为空
void SListPopBack(SL** pphead)
assert(*pphead);
if ((*pphead)->next == NULL)
free(*pphead);
*pphead = NULL;
else
SL* tail = *pphead;
/*while (tail->next != NULL)
tail = tail->next;
free(tail);
tail = NULL;*/
//如果直接freetail,那么链表的尾将会是一个野指针我们free tail的next
while (tail->next->next)
tail = tail->next;
free(tail->next);
tail->next = NULL;
链表的头删
先把第二个节点保存,以防找不到节点作为新头
void SListPopFront(SL** pphead)
assert(*pphead);
SL* cur = (*pphead)->next;;
free(*pphead);
*pphead = cur;
//先把第二个节点保存
链表的查找
遍历链表没什么好说的
SL *SListFind(SL* phead, SLDataType x)
assert(phead);
SL* cur = phead;
while (cur)
if (cur->data == x)
return cur;
else
cur = cur->next;
return NULL;
链表的指定节点后插
后插的时候记住保存下一个节点
void SListInsertAfter(SL* pos, SLDataType x)
SL* NewNode = BuySListNode(x);
SL* cur = pos->next;
pos->next = NewNode;
NewNode->next = cur;
链表的指定位置前插
先看看指定位置是不是头节点,如果是也就是头插,如果不是,我们要找到指定位置的前一个节点进行保存。
void SListInsert(SL** pphead, SL* pos, SLDataType x)
SL* NewNode = BuySListNode(x);
if (pos == *pphead)
NewNode->next = *pphead;
*pphead = NewNode;
else
//我们要找到pos的前一个位置才行
SL* posPrev = *pphead;
while (posPrev->next == pos)
posPrev = posPrev->next;
posPrev->next = NewNode;
NewNode->next = pos;
链表的删除
同样要找到指定节点的前一个,再进行删除
void SListErase(SL** pphead, SL* pos)
assert(pos);
if (*pphead == pos)
*pphead = (*pphead)->next;
free(pos);
else
SL* posPrev = *pphead;
while (posPrev->next != pos)
posPrev = posPrev->next;
posPrev->next = pos->next;
free(pos);
链表的销毁
先把下一个保存,以免找不到,然后遍历销毁
void SListDestory(SL** pphead)
SL* p=*pphead;
while (p)
*pphead = (*pphead)->next;
free(p);
p == NULL;
p = *pphead;
**
点个赞再走吧
**
以上是关于单链表的基本操作的主要内容,如果未能解决你的问题,请参考以下文章