什么是单链表
单链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针单向链接次序实现的。
程序实例
首先,我们创建一个头文件 Slist.h:
// Slist.h
#ifndef _SLIST_H_
#define _SLIST_H_
#include <stdio.h>
#include <stdlib.h>
// 定义单链表节点的数据类型
typedef int SLTDateType;
// 定义单链表节点的结构体
typedef struct SListNode {
SLTDateType data; // 存储的数据
struct SListNode* next; // 指向下一个节点的指针
} SLNode;
// 动态申请一个节点
SLNode* BuySListNode(SLTDateType x);
// 单链表打印
void SListPrint(SLNode* phead);
// 单链表尾插
void SListPushBack(SLNode** pphead, SLTDateType x);
// 单链表的头插
void SListPushFront(SLNode** pphead, SLTDateType x);
// 单链表的尾删
void SListPopBack(SLNode** pphead);
// 单链表头删
void SListPopFront(SLNode** pphead);
// 单链表查找
SLNode* SListFind(SLNode* phead, SLTDateType x);
// 单链表在pos位置之后插入x
void SListInsertAfter(SLNode* pos, SLTDateType x);
// 单链表在pos位置之后删除x
void SListEraseAfter(SLNode* pos);
// 单链表在pos位置插入x
void SListInsert(SLNode** pphead, SLNode* pos, SLTDateType x);
// 单链表删除pos位置的值
void SListErase(SLNode** pphead, SLNode* pos);
// 释放链表
void SListDestroy(SLNode** pphead);
#endif // _SLIST_H_
接下来,我们实现这些函数在 Slist.c 中:
// Slist.c
#include "Slist.h"
// 动态申请一个节点,返回一个节点首地址
SLNode* BuySListNode(SLTDateType x) {
SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
if (newnode == NULL) {
printf("malloc fail");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
// 单链表打印
void SListPrint(SLNode* plist) {
SLNode* cur = plist;
while (cur != NULL) {
printf("%d->", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
// 释放链表
void SListDestroy(SLNode** pphead) {
SLNode* cur = *pphead;
while (cur != NULL) {
SLNode* next = cur->next;
free(cur);
cur = next;
}
*pphead = NULL;
}
// 单链表尾插
void SListPushBack(SLNode** pphead, SLTDateType x) {
SLNode* newnode = BuySListNode(x);
if (*pphead == NULL) {
*pphead = newnode;
} else {
SLNode* tail = *pphead;
while (tail->next != NULL) {
tail = tail->next;
}
tail->next = newnode;
}
}
// 单链表的尾删
void SListPopBack(SLNode** pphead) {
assert(*pphead != NULL);
if ((*pphead)->next == NULL) {
free(*pphead);
*pphead = NULL;
} else {
SLNode* tail = *pphead;
while (tail->next->next != NULL) {
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
}
// 单链表的头插
void SListPushFront(SLNode** pphead, SLTDateType x) {
SLNode* newnode = BuySListNode(x);
newnode->next = *pphead;
*pphead = newnode;
}
// 单链表头删
void SListPopFront(SLNode** pphead) {
assert(*pphead != NULL);
SLNode* temp = *pphead;
*pphead = (*pphead)->next;
free(temp);
}
// 单链表查找
SLNode* SListFind(SLNode* phead, SLTDateType x) {
SLNode* cur = phead;
while (cur != NULL && cur->data != x) {
cur = cur->next;
}
return cur;
}
// 单链表在pos位置之后插入x
void SListInsertAfter(SLNode* pos, SLTDateType x) {
assert(pos != NULL);
SLNode* newnode = BuySListNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
// 单链表在pos位置之后删除x
void SListEraseAfter(SLNode* pos) {
assert(pos != NULL && pos->next != NULL);
SLNode* toDelete = pos->next;
pos->next = pos->next->next;
free(toDelete);
}
// 单链表在pos位置插入x
void SListInsert(SLNode** pphead, SLNode* pos, SLTDateType x) {
SLNode* newnode = BuySListNode(x);
if (pos == *pphead) {
SListPushFront(pphead, x);
} else {
SLNode* prev = *pphead;
while (prev->next != pos) {
prev = prev->next;
}
prev->next = newnode;
newnode->next = pos;
}
}
// 单链表删除pos位置的值
void SListErase(SLNode** pphead, SLNode* pos) {
if (pos == *pphead) {
SListPopFront(pphead);
} else {
SLNode* prev = *pphead;
while (prev->next != pos) {
prev = prev->next;
}
prev->next = pos->next;
free(pos);
}
}
最后,我们创建一个测试用例 main.c 来展示如何使用这些函数:
// main.c
#include <stdio.h>
#include "Slist.h"
int main() {
SLNode* plist = NULL;
// 尾部插入节点
SListPushBack(&plist, 1);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
// 打印链表
printf("Linked List after push back: ");
SListPrint(plist);
printf("\n");
// 头部插入节点
SListPushFront(&plist, 0);
SListPushFront(&plist, -1);
// 打印链表
printf("Linked List after push front: ");
SListPrint(plist);
printf("\n");
// 查找节点
SLNode* found = SListFind(plist, 2);
if (found) {
printf("Found: %d\n", found->data);
} else {
printf("Not found\n");
}
// 尾部删除节点
SListPopBack(&plist);
// 打印链表
printf("Linked List after pop back: ");
SListPrint(plist);
printf("\n");
// 头部删除节点
SListPopFront(&plist);
// 打印链表
printf("Linked List after pop front: ");
SListPrint(plist);
printf("\n");
// 释放链表
SListDestroy(&plist);
return 0;
}
要运行这个程序,您需要将 Slist.h、Slist.c 和 main.c 保存到您的计算机上,然后使用C编译器编译它们。例如,如果您使用的是GCC编译器,可以通过以下命令编译程序:
gcc -o main Slist.c main.c
./main
原文链接
https://blog.csdn.net/qq_52158753/article/details/129858629