1.链表
1.1链表的介绍
链表是一种常见的数据结构,用于存储一系列的元素,它与数组不同,链表中的元素不一定是连续存储在内存中的。链表由一系列节点组成,每个节点包含两个部分:数据域和指针域。数据域用来存储数据,而指针域则用来指向下一个节点。链表的最后一个节点的指针域通常指向空(null),表示链表的结束。
1.2链表的主要类型:
1.单链表(Singly Linked List):每个节点只包含一个指针,指向下一个节点。
2.双链表(Doubly Linked List):每个节点包含两个指针,一个指向前一个节点,另一个指向下一个节点。
3.循环链表(Circular Linked List):链表的最后一个节点的指针域指向第一个节点,形成一个环。

1.3链表的主要操作包括:
1.插入:在链表的某个位置插入一个新的节点。
2.删除:从链表中移除某个节点。
3.查找:在链表中查找某个特定值的节点。
4.遍历:按顺序访问链表中的每个节点。
链表的优点在于插入和删除操作不需要移动大量的元素,只需要改变相关节点的指针即可。但是,链表的缺点是访问元素不如数组那样可以直接通过索引快速访问,需要从头节点开始依次遍历到目标节点。此外,链表的每个节点都需要额外的空间来存储指针。
在实际应用中,链表常用于实现栈、队列、哈希表等数据结构,也用于解决某些特定问题,如LRU缓存淘汰算法等。
2.代码的展示
2.1链表的生成及销毁
typedef int SLTINT;
//链表是由节点组成的
typedef struct Linklist//链表
{
SLTINT data;
struct Linklist* next;
}List;
void LIDestory(List** pphead)
{
assert(pphead);
assert(*pphead);
List* pcur = *pphead;
while (pcur)
{
List* next = pcur->next;
free(pcur);
pcur = next;
}
*pphead = NULL;
}
2.2链表的初始化
//void Slisttext01()
//{
// List* node1 = (List*)malloc(sizeof(List));
// node1->data = 1;
// List* node2 = (List*)malloc(sizeof(List));
// node2->data = 2;
// List* node3 = (List*)malloc(sizeof(List));
// node3->data = 3;
// List* node4 = (List*)malloc(sizeof(List));
// node4->data = 4;
// node1->next = node2;
// node2->next = node3;
// node3->next = node4;
// node4->next = NULL;
// List* plist = node1;
// LIprint(plist);
//}
2.3链表的打印及插入
void LIprint(List* phead)
{
List* pucr = phead;
while (pucr)
{
printf("%d->", pucr->data);
pucr = pucr->next;
}
printf("NULL\n");
}
//申请空间
List* LIBuynode(SLTINT x)
{
List* newnode = (List*)malloc(sizeof(List));
if (newnode == NULL)
{
perror("malloc fail!");
exit(1);
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
void LIPushBack(List** pphead, SLTINT x)
{
assert(pphead);
//链表为空,新节点作为phead
List* newnode = LIBuynode(x);
if (*pphead == NULL)
{
*pphead = newnode;
return;
}
//链表不为空,找尾节点插入
List* Pcur = *pphead;
while (Pcur->next)
{
Pcur = Pcur->next;
}
//尾节点
Pcur->next = newnode;
}
void LIPushFront(List** pphead, SLTINT x)
{
assert(pphead);
//链表为空,找节点作为phead
List* newnode = LIBuynode(x);
List* Pcur = *pphead;
newnode->next = Pcur;
*pphead = newnode;
//链表不为空,找头节点插入
}
2.4链表的删除
void LIPopBack(List** pphead)
{
assert(pphead);
assert(*pphead);
//链表有一个节点
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
return;
}
else
{
//链表有多个节点
List* Pcur = *pphead;
List* prev = NULL;
while (Pcur->next!=NULL)
{
prev = Pcur;
Pcur = Pcur->next;
}
prev->next = NULL;
//释放尾节点
free(Pcur);
Pcur = NULL;
}
}
//头删
void LIPopFront(List** pphead)
{
assert(pphead);
assert(*pphead);
List* po = (*pphead)->next;
free(*pphead);
*pphead = po;
}
2.5链表的指定位置的查找及删除插入
//查找链表
List* LIFind(List** pphead, SLTINT x)
{
assert(pphead);
List* pcur = *pphead;
while (pcur)
{
if (pcur->data == x)
{
return pcur;
}
pcur = pcur->next;
}
//没有找到
return NULL;
}
void LIInsert(List** pphead, List* pos, SLTINT x)
{
assert(pphead);
assert(*pphead);
assert(pos);
if (pos == *pphead)
{
LIPushFront(pphead,x);
return;
}
//pos不是头结果的情况
List* newnode = LIBuynode(x);
List* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = newnode;
newnode->next = pos;
}
void LIInsertafter(List* pos, SLTINT x)
{
assert(pos);
List* newnode = LIBuynode(x);
newnode->next = pos->next;
pos->next = newnode;
}
void LIstrase(List** pphead, List*pos)
{
assert(pphead);
assert(*pphead);
assert(pos);
if (*pphead == pos)
{
//头删
LIPopFront(pphead);
return;
}
List* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
pos = NULL;
}
void LIstraseafter( List* pos)
{
assert(pos);
assert(pos->next);
List* dit = pos->next;
pos->next = pos->next->next;
free(dit);
dit = NULL;
}
3.总代码的展示
.h头文件
#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLTINT;
//链表是由节点组成的
typedef struct Linklist//链表
{
SLTINT data;
struct Linklist* next;
}List;
//链表的打印
void LIprint(List* phead);
//链表的尾部插入
void LIPushBack(List** pphead, SLTINT x);
//链表的头部插入
void LIPushFront(List** pphead, SLTINT x);
//链表申请空间
List* LIBuynode(List x);
//链表的尾部删除
void LIPopBack(List** pphead);
//链表的头部删除
void LIPopFront(List** pphead);
//查找链表
List* LIFind(List** pphead, SLTINT x);
//在指定位置之前插入数据
void LIInsert(List** pphead, List* pos, SLTINT x);
//在指定位置之后插入数据
void LIInsertafter(List* pos, SLTINT x);
//删除指定位置的节点
void LIstrase(List* pphead, List* pos);
//删除指定位置之后的节点
void LIstraseafter( List* pos);
//销毁链表
void LIDestory(List** pphead);
.c源代码
#define _CRT_SECURE_NO_WARNINGS
#include "list.h"
//链表的打印
void LIprint(List* phead)
{
List* pucr = phead;
while (pucr)
{
printf("%d->", pucr->data);
pucr = pucr->next;
}
printf("NULL\n");
}
List* LIBuynode(SLTINT x)
{
List* newnode = (List*)malloc(sizeof(List));
if (newnode == NULL)
{
perror("malloc fail!");
exit(1);
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
void LIPushBack(List** pphead, SLTINT x)
{
assert(pphead);
//链表为空,新节点作为phead
List* newnode = LIBuynode(x);
if (*pphead == NULL)
{
*pphead = newnode;
return;
}
//链表不为空,找尾节点插入
List* Pcur = *pphead;
while (Pcur->next)
{
Pcur = Pcur->next;
}
//尾节点
Pcur->next = newnode;
}
void LIPushFront(List** pphead, SLTINT x)
{
assert(pphead);
//链表为空,找节点作为phead
List* newnode = LIBuynode(x);
List* Pcur = *pphead;
newnode->next = Pcur;
*pphead = newnode;
//链表不为空,找头节点插入
}
void LIPopBack(List** pphead)
{
assert(pphead);
assert(*pphead);
//链表有一个节点
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
return;
}
else
{
//链表有多个节点
List* Pcur = *pphead;
List* prev = NULL;
while (Pcur->next!=NULL)
{
prev = Pcur;
Pcur = Pcur->next;
}
prev->next = NULL;
//释放尾节点
free(Pcur);
Pcur = NULL;
}
}
//头删
void LIPopFront(List** pphead)
{
assert(pphead);
assert(*pphead);
List* po = (*pphead)->next;
free(*pphead);
*pphead = po;
}
//查找链表
List* LIFind(List** pphead, SLTINT x)
{
assert(pphead);
List* pcur = *pphead;
while (pcur)
{
if (pcur->data == x)
{
return pcur;
}
pcur = pcur->next;
}
//没有找到
return NULL;
}
void LIInsert(List** pphead, List* pos, SLTINT x)
{
assert(pphead);
assert(*pphead);
assert(pos);
if (pos == *pphead)
{
LIPushFront(pphead,x);
return;
}
//pos不是头结果的情况
List* newnode = LIBuynode(x);
List* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = newnode;
newnode->next = pos;
}
void LIInsertafter(List* pos, SLTINT x)
{
assert(pos);
List* newnode = LIBuynode(x);
newnode->next = pos->next;
pos->next = newnode;
}
void LIstrase(List** pphead, List*pos)
{
assert(pphead);
assert(*pphead);
assert(pos);
if (*pphead == pos)
{
//头删
LIPopFront(pphead);
return;
}
List* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
pos = NULL;
}
void LIstraseafter( List* pos)
{
assert(pos);
assert(pos->next);
List* dit = pos->next;
pos->next = pos->next->next;
free(dit);
dit = NULL;
}
void LIDestory(List** pphead)
{
assert(pphead);
assert(*pphead);
List* pcur = *pphead;
while (pcur)
{
List* next = pcur->next;
free(pcur);
pcur = next;
}
*pphead = NULL;
}
测试代码
#include "list.h"
//void Slisttext01()
//{
// List* node1 = (List*)malloc(sizeof(List));
// node1->data = 1;
// List* node2 = (List*)malloc(sizeof(List));
// node2->data = 2;
// List* node3 = (List*)malloc(sizeof(List));
// node3->data = 3;
// List* node4 = (List*)malloc(sizeof(List));
// node4->data = 4;
// node1->next = node2;
// node2->next = node3;
// node3->next = node4;
// node4->next = NULL;
// List* plist = node1;
// LIprint(plist);
//}
void Slisttext02()
{
List* plist = NULL;
LIPushBack(&plist, 1);
LIPushBack(&plist, 2);
LIPushBack(&plist, 3);
LIPushBack(&plist, 4);
LIprint(plist);
LIPopBack(&plist);
/*LIPopBack(&plist);
LIPopBack(&plist);
LIPopBack(&plist);
LIPopBack(&plist);*/
//LIPopFront(&plist);
LIprint(plist);
}
void Slisttext03()
{
List* plist = NULL;
LIPushFront(&plist, 1);
LIPushFront(&plist, 2);
LIPushFront(&plist, 3);
LIPushFront(&plist, 4);
LIprint(plist);
List*Findet= LIFind(&plist, 2);
LIInsert(&plist, Findet, 6);
LIprint(plist);
List* Findert = LIFind(&plist, 1);
LIInsertafter(Findert, 66);
LIprint(plist);
List* Findrt = LIFind(&plist, 1);
LIstrase(&plist, Findrt);
LIprint(plist);
/*if (Findet)
{
printf("找到了!\n");
}
else
{
printf("没有找到\n");
}*/
}
int main()
{
// Slisttext01();
Slisttext02();
Slisttext03();
return 0;
}
14万+

被折叠的 条评论
为什么被折叠?



