前言
这是我由C语言写的单链表,希望对大家有帮助。
1.SeparateList.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
//_CRT_SECURE_NO_WARNINGS
//定义头文件
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
// 单链表节点定义
typedef int SLTDateType;
typedef struct SListNode
{
SLTDateType data;
struct SListNode* next;
}SLTNode;
// 单链表打印
void SListPrint(const SLTNode* pSListNode);
// 单链表头插
void SListPushFront(SLTNode** ppSListNode, const SLTDateType x);
// 单链表尾插
void SListPushBack(SLTNode** ppSListNode, const SLTDateType x);
// 单链表尾删
void SListPopBack(SLTNode** ppSListNode);
// 单链表头删
void SListPopFront(SLTNode** ppSListNode);
// 单链表的销毁
void SListDestroy(SLTNode** ppSListNode);
// 单链表查找
SLTNode* SListFind(const SLTNode* pSListNode, const SLTDateType x);
// 单链表在pos位置之前插入x
void SListInsertFront(SLTNode** ppSListNode, SLTNode* pos, const SLTDateType x);
// 单链表在pos位置之后插入x
void SListInsertAfter(SLTNode* pos, const SLTDateType x);
// 单链表删除pos位置之前的值
void SListEraseFront(SLTNode** ppSListNode, SLTNode* pos);
// 单链表删除pos位置之后的值
void SListEraseAfter(SLTNode* pos);
// 单链表删除pos位置
void SListErase(SLTNode** ppSListNode, SLTNode* pos);
2.SeparateList.c
#include "SeparateList.h"
// 单链表打印
void SListPrint(const SLTNode* pSListNode)
{
SLTNode* cur;
for (cur = (SLTNode*)pSListNode;cur != NULL;cur = cur->next)
printf("%d->", cur->data);
printf("NULL\n");
}
// 动态申请一个节点
static SLTNode* BuySListNode(const SLTDateType x)
{
SLTNode* new_node = (SLTNode*)malloc(sizeof(SLTNode));
if (!new_node)
{
perror("BuySListNode");
exit(-1);
}
new_node->data = x;
new_node->next = NULL;
return new_node;
}
// 单链表的头插
void SListPushFront(SLTNode** ppSListNode, const SLTDateType x)
{
assert(ppSListNode);
SLTNode* new_node = BuySListNode(x);
new_node->next = *ppSListNode;
*ppSListNode = new_node;
}
// 单链表尾插
void SListPushBack(SLTNode** ppSListNode, const SLTDateType x)
{
assert(ppSListNode);
SLTNode* new_node = BuySListNode(x);
// 链表没数据时
if (!*ppSListNode)
*ppSListNode = new_node;
// 链表有数据时
else
{
// 找尾部
SLTNode* tail;
for (tail = *ppSListNode;tail->next;tail = tail->next);
tail->next = new_node;
}
}
// 单链表的尾删
void SListPopBack(SLTNode** ppSListNode)
{
assert(ppSListNode);
assert(*ppSListNode);
// 链表有一个数据时
if (!(*ppSListNode)->next)
{
free(*ppSListNode);
*ppSListNode = NULL;
}
// 链表有多个数据时
else
{
// 找尾部前一个
SLTNode* tail;
for (tail = *ppSListNode;tail->next->next;tail = tail->next);
free(tail->next);
tail->next = NULL;
}
}
// 单链表头删
void SListPopFront(SLTNode** ppSListNode)
{
assert(ppSListNode);
assert(*ppSListNode);
SLTNode* tmp = *ppSListNode;
*ppSListNode = (*ppSListNode)->next;
free(tmp);
tmp = NULL;
}
// 单链表的销毁
void SListDestroy(SLTNode** ppSListNode)
{
assert(ppSListNode);
SLTNode* cut = *ppSListNode;
while (cut)
{
SLTNode* tmp = cut->next;
free(cut);
cut = tmp;
}
*ppSListNode = NULL;
}
// 单链表查找
SLTNode* SListFind(const SLTNode* pSListNode, const SLTDateType x)
{
assert(pSListNode);
while (pSListNode)
{
if (pSListNode->data == x)
return (SLTNode*)pSListNode;
pSListNode = pSListNode->next;
}
return NULL;
}
// 单链表在pos位置之前插入x
void SListInsertFront(SLTNode** ppSListNode, SLTNode* pos, const SLTDateType x)
{
assert(ppSListNode && pos);
SLTNode* new_node = BuySListNode(x);
if (*ppSListNode == pos)
{
SListPushFront(ppSListNode, x);
}
else
{
SLTNode* cut;
for (cut = *ppSListNode;cut->next != pos;cut = cut->next)
assert(cut);
new_node->next = cut->next;
cut->next = new_node;
}
}
// 单链表在pos位置之后插入x
void SListInsertAfter(SLTNode* pos, const SLTDateType x)
{
assert(pos);
SLTNode* new_node = BuySListNode(x);
new_node->next = pos->next;
pos->next = new_node;
}
// 单链表删除pos位置之前的值
void SListEraseFront(SLTNode** ppSListNode, SLTNode* pos)
{
assert(ppSListNode && pos);
assert(*ppSListNode != pos);
if ((*ppSListNode)->next == pos)
SListPopFront(ppSListNode);
else
{
SLTNode* cut;
for (cut = *ppSListNode;cut->next->next != pos;cut = cut->next)
assert(cut);
SLTNode* tmp = cut->next;
cut->next = cut->next->next;
free(tmp);
tmp = NULL;
}
}
// 单链表删除pos位置之后的值
void SListEraseAfter(SLTNode* pos)
{
assert(pos && pos->next);
SLTNode* tmp = pos->next;
pos->next = pos->next->next;
free(tmp);
tmp = NULL;
}
// 单链表删除pos位置的值
void SListErase(SLTNode** ppSListNode, SLTNode* pos)
{
assert(ppSListNode && pos);
if (*ppSListNode == pos)
SListPopFront(ppSListNode);
else
{
SLTNode* cut;
for (cut = *ppSListNode;cut->next != pos;cut = cut->next)
assert(cut);
cut->next = cut->next->next;
free(pos);
}
}
4.SeparateListMain.c
#include "SeparateList.h"
// 测试1:单链表打印与单链表的头插与单链表头删
void SLTest1()
{
SLTNode* plist = NULL;
SListPushFront(&plist, 1);
SListPushFront(&plist, 2);
SListPushFront(&plist, 3);
SListPushFront(&plist, 4);
SListPrint(plist);
SListPopFront(&plist);
SListPopFront(&plist);
SListPrint(plist);
SListPopFront(&plist);
SListPopFront(&plist);
SListPrint(plist);
SListDestroy(&plist);
}
// 测试2:单链表打印与单链表尾插与单链表的尾删
void SLTest2()
{
SLTNode* plist = NULL;
SListPushBack(&plist, 1);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 4);
SListPrint(plist);
SListPopBack(&plist);
SListPopBack(&plist);
SListPrint(plist);
SListPopBack(&plist);
SListPopBack(&plist);
SListPrint(plist);
SListDestroy(&plist);
}
// 测试3:单链表打印与单链表尾插与单链表的销毁
void SLTest3()
{
SLTNode* plist = NULL;
SListPushBack(&plist, 1);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 4);
SListPrint(plist);
SListDestroy(&plist);
SListPrint(plist);
SListDestroy(&plist);
}
// 测试4:单链表打印与单链表尾插与单链表查找
void SLTest4()
{
SLTNode* plist = NULL;
SListPushBack(&plist, 1);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 4);
SListPrint(plist);
SLTNode* pos = SListFind(plist, 2);
if (pos)
{
printf("Not exist!\n");
}
else
{
printf("Exist\n");
}
SListPrint(plist);
SListDestroy(&plist);
}
// 测试5:单链表打印与单链表尾插与单链表查找与单链表在pos位置之后插入x与单链表删除pos位置之后的值
void SLTest5()
{
SLTNode* plist = NULL;
SListPushBack(&plist, 1);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 4);
SListPrint(plist);
SListInsertAfter(SListFind(plist, 2), 5);
SListPrint(plist);
SListEraseAfter(SListFind(plist, 2));
SListPrint(plist);
SListInsertAfter(SListFind(plist, 4), 5);
SListPrint(plist);
SListEraseAfter(SListFind(plist, 4));
SListPrint(plist);
SListDestroy(&plist);
}
// 测试6:单链表打印与单链表尾插与单链表查找与单链表在pos位置之前插入x与单链表删除pos位置之前的值
void SLTest6()
{
SLTNode* plist = NULL;
SListPushBack(&plist, 1);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 4);
SListPrint(plist);
SListInsertFront(&plist, SListFind(plist, 2), 5);
SListPrint(plist);
SListEraseFront(&plist, SListFind(plist, 2));
SListPrint(plist);
SListInsertFront(&plist, SListFind(plist, 1), 5);
SListPrint(plist);
SListEraseFront(&plist, SListFind(plist, 1));
SListPrint(plist);
SListDestroy(&plist);
}
// 测试7:单链表打印与单链表尾插与单链表查找与单链表删除pos位置的值
void SLTest7()
{
SLTNode* plist = NULL;
SListPushBack(&plist, 1);
SListPushBack(&plist, 2);
SListPushBack(&plist, 3);
SListPushBack(&plist, 4);
SListPrint(plist);
SListErase(&plist, SListFind(plist, 1));
SListPrint(plist);
SListErase(&plist, SListFind(plist, 3));
SListPrint(plist);
SListErase(&plist, SListFind(plist, 4));
SListPrint(plist);
SListDestroy(&plist);
}
int main(void)
{
printf("测试1:单链表打印与单链表的头插与单链表头删\n");
SLTest1();
printf("测试2:单链表打印与单链表尾插与单链表的尾删\n");
SLTest2();
printf("测试3:单链表打印与单链表尾插与单链表的销毁\n");
SLTest3();
printf("测试4:单链表打印与单链表尾插与单链表查找\n");
SLTest4();
printf("测试5:单链表打印与单链表尾插与单链表查找与单链表在pos位置之后插入x与单链表删除pos位置之后的值\n");
SLTest5();
printf("测试6:单链表打印与单链表尾插与单链表查找与单链表在pos位置之前插入x与单链表删除pos位置之前的值\n");
SLTest6();
printf("测试7:单链表打印与单链表尾插与单链表查找与单链表删除pos位置的值\n");
SLTest7();
return 0;
}