上一篇博客我们学习了线性表中的顺序表,这一篇博客让我们继续往下了解线性表的链表,链表分为好几种结构,活不多说,让我们开始学习吧!
目录
1.链表
2.链表的结构
3.单链表的实现
SList.h文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int ALTDataType;
//创建结构体,用来创建链表组成元素
typedef struct SListNode
{
ALTDataType data;//链表数据
struct SListNode* next;//链表指向下一个元素的指针,指向下一个节点的位置
}SLN;
//开辟空间来存入数据
SLN* BuySListNode(ALTDataType x);
//打印链表
void SListPrint(SLN* phead);
//头插
void sListPushFront(SLN** pphead, ALTDataType x);
//尾插
void sListPushBack(SLN** pphead, ALTDataType x);
//头删
void sListPopFront(SLN** pphead);
//尾删
void sListPopBack(SLN** pphead);
//查找链表
SLN* sListFind(SLN* phead, ALTDataType x);
//修改对应链表位置的数据
void sListModify(SLN* phead, SLN* pos, ALTDataType x, ALTDataType y);
//任意位置的插入,在pos位置的前一个位置插入
void sListInsert(SLN** pphead, SLN* pos, ALTDataType x);
//任意位置的删除
void sListErase(SLN** pphead, SLN* pos);
//销毁链表
void destorySList(SLN* phead);
SList.c文件
#include"SList.h"
//开辟空间来存入数据
SLN* BuySListNode(ALTDataType x)
{
SLN* newnode = (SLN*)malloc(sizeof(SLN));
if (newnode == NULL)
{
perror("malloc");
return NULL;
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
//打印链表
void SListPrint(SLN* phead)
{
assert(phead);
SLN* cur = phead;
while (cur)
{
printf("%d->", cur->data);
cur = cur->next;
}
printf("\n");
}
//头插
//想要头插,我们要把新节点的地址给到头节点,再把新节点定义为新的头节点
void sListPushFront(SLN** pphead, ALTDataType x)
{
SLN* newnode = BuySListNode(x);
newnode->next = *pphead;
*pphead = newnode;
}
//尾插
void sListPushBack(SLN** pphead, ALTDataType x)
{
SLN* newnode = BuySListNode(x);
//若一开始链表为空,我们直接插入一个新节点
if (*pphead == NULL)
{
*pphead = newnode;
}
//我们要创建一个变量,找到链表的尾端,从尾端插入
SLN* tail = *pphead;
while (tail->next)
{
tail = tail->next;
}
tail->next = newnode;//尾节点链接新节点
}
//头删
void sListPopFront(SLN** pphead)
{
assert(*pphead);
SLN* next = (*pphead)->next;//*小于->的优先级,编译器不通过
free(*pphead);
*pphead = NULL;
*pphead = next;
}
//尾删
void sListPopBack(SLN** pphead)
{
assert(*pphead);
//当只有一个节点时
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
return;
}
SLN* tail = *pphead;
SLN* prev = NULL;
while (tail->next)
{
prev = tail;
tail = tail->next;
}
free(tail);
tail = NULL;
prev->next = NULL;
}
//查找链表
SLN* sListFind(SLN* phead, ALTDataType x)
{
assert(phead);
SLN* cur = phead;
while (cur)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
//修改对应链表位置的数据
void sListModify(SLN* phead, SLN* pos, ALTDataType x, ALTDataType y)
{
pos = sListFind(phead, x);
pos->data = y;
}
//任意位置的插入,在pos位置的前一个位置插入
void sListInsert(SLN** pphead, SLN* pos, ALTDataType x)
{
if (pos == *pphead)
{
sListPushFront(pphead, x);
return;
}
SLN* newnode = BuySListNode(x);
SLN* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = newnode;
newnode->next = pos;
}
//任意位置的删除,删除pos位置的值
void sListErase(SLN** pphead, SLN* pos)
{
if (pos == *pphead)
{
sListPopFront(pphead);
return;
}
SLN* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
pos = NULL;
}
//销毁链表,这些空间,我们要一个一个释放,防止内存泄漏
void destorySList(SLN* phead)
{
assert(phead);
SLN* tail = phead->next;
while (tail)
{
SLN* next = tail->next;
free(tail);
tail = NULL;
tail = next;
}
free(phead);
phead = NULL;
}
test.c文件
#include"SList.h"
void Test1()
{
SLN* plist = NULL;
SLN* pos = NULL;
sListPushFront(&plist, 4);
sListPushFront(&plist, 3);
sListPushFront(&plist, 2);
sListPushFront(&plist, 1);
SListPrint(plist);
sListPushBack(&plist, 5);
sListPushBack(&plist, 6);
sListPushBack(&plist, 7);
sListPushBack(&plist, 8);
SListPrint(plist);
sListPopFront(&plist);
sListPopFront(&plist);
SListPrint(plist);
sListPopBack(&plist);
sListPopBack(&plist);
SListPrint(plist);
pos = sListFind(plist, 5);
if (pos == NULL)
{
printf("找不到该数据\n");
}
else
{
printf("已找到该数据,现在进行修改\n");
sListModify(plist, pos, 5, 50);
}
SListPrint(plist);
pos = sListFind(plist, 50);
if (pos == NULL)
{
printf("找不到该数据\n");
}
else
{
printf("已找到该数据,现在进行在pos前插入数据\n");
sListInsert(&plist, pos, 20);
}
SListPrint(plist);
pos = sListFind(plist, 20);
if (pos == NULL)
{
printf("找不到该数据\n");
}
else
{
printf("已找到该数据,现在进行对pos位置数据的删除\n");
sListErase(&plist, pos);
}
SListPrint(plist);
destorySList(plist);
printf("链表已销毁\n");
}
int main()
{
Test1();
return 0;
}
好了,今天的内容就是这些,我们下期再见铁汁们!
感谢品读!!!