目录
引言
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。像上一篇博客就是一个顺序表的构建。
而链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
单链表
数据节点
我们知道链表结构和顺序表不同,不是一块连续的空间,而是一个个的数据节点,所以我们先要规定一个数据节点是怎么样的,首先要包含想要储存的数据,然后是要包含指向下一个节点的指针,只有这样才能把一个个松散的节点串联在一起。
//确定数据节点中储存的数据类型
typedef int SListDateType;
//节点的结构
struct SListNode
{
SListDateType val;
struct SListNode* next;
};
typedef struct SListNode SListNode;
创建一个数据节点
SListNode* BuySListNode(SListDateType x)
{
SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
assert(newnode);
newnode->val = x;
newnode->next = NULL;
}
这没什么好说的,就是根据数据节点结构开辟空间,对其初始化。
打印链表
void SListPrint(SListNode* head)
{
SListNode* cur = head;
while (cur != NULL)
{
printf("%d->", cur->val);
cur = cur->next;
}
printf("NULL");
}
尾插数据
void SListPushBack(SListNode** pphead, SListDateType x)
{
SListNode* newnode = BuySListNode(x);
if (*pphead == NULL)
{
*pphead = newnode;
return;
}
SListNode* cur = *pphead;
while (cur->next != NULL)
{
cur = cur->next;
}
cur->next = newnode;
}
特别要注意,这里传的是头节点的二级指针,因为可能要改变指针的值,我们知道在C语言中如果想要传值后改变相应的值,就要传相应的指针,因为想改变一级指针,就要传二级指针。
头插数据
void SListPushFront(SListNode** pphead, SListDateType x)
{
SListNode* newnode = BuySListNode(x);
newnode->next = *pphead;
*pphead = newnode;
}
尾删数据
void SListPopBack(SListNode** pphead)
{
assert(*pphead);
SListNode* prev = NULL;
SListNode* cur = *pphead;
while (cur->next != NULL)
{
prev = cur;
cur = cur->next;
}
free(cur);
cur = NULL;
if (prev == NULL)
{
*pphead = prev;
}
else
{
prev->next = NULL;
}
}
头删数据
void SListPopFront(SListNode** pphead)
{
assert(*pphead);
SListNode* cur = *pphead;
*pphead = cur->next;
free(cur);
cur = NULL;
}
找数据
SListNode* SListFind(SListNode* phead, SListDateType x)
{
assert(phead);
SListNode* cur = phead;
while (cur != NULL)
{
if (cur->val == x)
{
return cur;
}
cur = cur->next;
}
return cur;
}
指定位置后插入数据
void SListInsertAfter(SListNode* pos, SListDateType x)
{
assert(pos);
SListNode* newnode = BuySListNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
数指定位置后删数据
void SListEraseAfter(SListNode* pos)
{
assert(pos);
assert(pos->next);
SListNode* cur = pos->next;
pos->next = cur->next;
free(cur);
cur = NULL;
}
链表销毁
void SListDestroy(SListNode* phead)
{
assert(phead);
SListNode* cur = phead;
SListNode* back = phead->next;
while (back != NULL)
{
free(cur);
cur = back;
back = back->next;
}
free(cur);
cur = NULL;
}