线性表之单链表(数据结构)(VS)(C语言)(SeparateList)


前言

  这是我由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;
}

效果

在这里插入图片描述


看完给个关注,多谢了!!!

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值