1.链表的概念和结构:
链表是⼀种物理存储结构上⾮连续、⾮顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
链表的结构跟⽕⻋⻋厢相似。
在链表⾥,每节“⻋厢”是什么样的呢?
链表⾥的每节"⻋厢"都是独⽴申请下来的空间,我们称之为“结点/节点”。
节点的组成主要有两个部分:当前节点要保存的数据和保存下⼀个节点的地址(指针变量)。
2.链表的分类:
(1)单向/多向:
(2)带头/不带头:
(3)循环/不循环:
3.单链表的实现:
struct SList {
int data;
struct SList* next;
};
头文件:
//定义链表节点的结构
typedef int SLDataType;
typedef struct SList {
SLDataType data;
struct SList* next;
}SLNode;
//打印链表
void SLNPrint(SLNode* phead);
//头/尾 插入/删除
void SLPushback(SLNode** pphead, SLDataType x);
void SLPushFront(SLNode** pphead, SLDataType x);
void SLPopBack(SLNode** pphead);
void SLPopFront(SLNode** pphead);
//指定位置之前插入
void SLInsert(SLNode** pphead, SLNode* pos, SLDataType x);
//指定位置之后插入
void SLInsertAfter(SLNode* pos, SLDataType x);
//删除指定节点
void SLErase(SLNode** pphead, SLNode* pos);
//销毁链表
void SLDesTroy(SLNode** pphead);
源文件:
void SLNPrint(SLNode* phead) {
assert(phead);
SLNode* pcur = phead;
while (pcur)
{
printf("%d ", pcur->data);
pcur = pcur->next;
}
}
SLNode* SLBuyNode(SLDataType x)
{
SLNode* node = (SLNode*)malloc(sizeof(SLNode));
node->data = x;
node->next = NULL;
return node;
}
void SLPushback(SLNode** pphead, SLDataType x) {
assert(pphead);
SLNode* node = SLBuyNode(x);
if (*pphead == NULL)
{
*pphead = node;
}
SLNode* pcur = *pphead;
while (pcur->next != NULL) {
pcur = pcur->next;
}
pcur->next = node;
}
void SLPushFront(SLNode** pphead, SLDataType x) {
assert(pphead);
SLNode* node = SLBuyNode(x);
node->next = *pphead;
*pphead = node;
}
void SLPopBack(SLNode** pphead) {
assert(pphead);
assert(*pphead);
//只有一个节点
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
return;
}
SLNode* prev = NULL;
SLNode* ptail = *pphead;
while (ptail->next != NULL)
{
prev = ptail;
ptail = ptail->next;
}
prev->next = NULL;
free(ptail);
ptail = NULL;
}
void SLPopFront(SLNode** pphead) {
SLNode* ret = *pphead;
pphead = (*pphead)->next;
free(ret);
ret = NULL;
}
void SLInsert(SLNode** pphead, SLNode* pos, SLDataType x) {
assert(pphead);
assert(pos);
assert(*pphead);
SLNode* node = SLBuyNode(x);
if (*pphead == pos)
{
node->next = pos;
*pphead = node;
return;
}
SLNode* ret = *pphead;
while (ret->next!=pos)
{
ret = ret->next;
}
ret->next= node;
ret->next->next = pos;
ret = NULL;
}
void SLInsertAfter(SLNode* pos, SLDataType x) {
assert(pos);
SLNode* node = SLBuyNode(x);
node->next = pos->next;
pos->next = node;
}
void SLErase(SLNode** pphead, SLNode* pos) {
assert(pphead);
assert(pos);
if (*pphead == pos)
{
*pphead = pos->next;
free(pos);
pos = NULL;
return;
}
SLNode* ret = *pphead;
while (ret->next != pos)
{
ret = ret->next;
}
ret->next = pos->next;
free(pos);
pos = NULL;
}
void SLDesTroy(SLNode** pphead) {
assert(pphead);
SLNode* pcur = *pphead;
while (pcur)
{
SLNode* ret = pcur->next;
free(pcur);
pcur = ret;
}
*pphead = NULL;
}