C语言数据结构之单链表

目录

前言:

一、基本思路

二、开工

1、增加内容

(1)首先要整个新数据

(2)头插

(3)尾插

(4)自定义插入

2、删减内容

(1)头删

(2)尾删

(3)自定义位置删除

3、寻找内容

4、打印单链表

5、删除单链表

三、后话


前言:

之前在刚接触数据结构时学习了顺序表,但是顺序表的修改牵一发而动全身,加个东西减个东西整体地址大多要变动,所以在这之后我们学习了单链表这样操作相对方便一点,同样的对指针要求也麻烦了点

一、基本思路

单链表不用像顺序表一样一次性申请一大堆内存,可以放一个申请一段空间然后用指针链接这些数据的存放顺序便没有要求,操作起来也相对轻松

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLTDateType;
typedef struct SListNode
{
	SLTDateType data;
	struct SListNode* next;
}SListNode;

与顺序表相同的头文件以及重定义类型,不同的是结构体内容,放了下一个数据所在位置的指针

二、开工

1、增加内容

(1)首先要整个新数据

SListNode* BuySListNode(SLTDateType x)
{
	SListNode* new = (SListNode*)malloc(sizeof(SListNode));
	if (new == NULL)
	{
		perror("malloc fail");
		return NULL;
	}
	new->data = x;
	new->next = NULL;
	return new;
}

返回新数据的地址

(2)头插

void SListPushFront(SListNode** pplist, SLTDateType x) {
	SListNode* new= BuySListNode(x);
	new->next = *pplist;
	*pplist = new;

}

将头改成新的就好,原来的头放在新头的next里

(3)尾插

void SListPushBack(SListNode** pplist, SLTDateType x)
{
	SListNode* new = BuySListNode(x);
	
	if (*pplist == NULL)
	{
		*pplist = new;
	}
	else {
		SListNode* tail = *pplist;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}tail->next = new;
	}
	
}

与头插不同,多了个找尾的工作(这里就比顺序表麻烦了点╮(╯﹏╰)╭)

(4)自定义插入

思路是新数据接上上一个的next再在自己的next内存放下一个数据的地址(因为只存放了下一个数据的地址,所以在自定义位置后插入会比在前插入容易)

思路如图

void SListInsertAfter(SListNode* plist, SListNode* pos, SLTDateType x) {
	assert(pos);
	SListNode* Next, *new;
	Next = pos->next;
	new = BuySListNode(x);
	new->next = Next;
	pos->next = new;

}

 同理可以通过修改pos来简化头插(尾插还得提前找尾)

2、删减内容

(1)头删

void SListPopFront(SListNode** pplist) {
	assert(pplist);
	SListNode* first = *pplist;
	*pplist = first->next;
	free(first);
	first = NULL;
}

完事后记得把原来头的内存释放掉就好

(2)尾删

void SListPopBack(SListNode** pplist) {
	assert(pplist);
	if ((*pplist)->next== NULL)
	{
		free(*pplist);
		*pplist = NULL;
	}
	else {
		SListNode* tail = *pplist;
		while (tail->next->next!=NULL)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;

	}
}

除了找尾以外和头删大同小异(笑)

(3)自定义位置删除

将前后链接起来自己释放就好

void SListEraseAfter(SListNode* pos) {
	assert(pos);
	SListNode* Next;
	assert(pos->next);
	Next = pos->next->next;
	free(pos->next);
	pos->next = Next;
}

3、寻找内容

SListNode* SListFind(SListNode* plist, SLTDateType x) {
	assert(plist);
	SListNode* c = plist;
	while (c)
	{
		if (c->data == x)
		{
			return c;
		}
		else {
			c= c->next;
		}
	}return NULL;
}

找得到返回地址找不到只能返回个空了罢

4、打印单链表

void SListPrint(SListNode* plist)
{
	SListNode* c = plist;
	while (c )
	{
		printf("%d->",c->data);
			c=c->next;
	}printf("NULL\n");
}

不能用数组方式了呢只好一步步看有没有打完

5、删除单链表

走一步释放一步;( ̄︶ ̄)↗( ̄︶ ̄)↗( ̄︶ ̄)↗

void SListDestroy(SListNode* plist)
{
	assert(plist);
	SListNode* a = plist;
	while (plist->next!=NULL)
	{
		plist = plist->next;
		free(a);
		a = plist;
	}free(a);
}

三、后话

对指针要求比顺序表高了那么一点点(时不时就能看见自己的指针有一种野性的美感<( ̄ ﹌  ̄)>  让人欲罢不能)

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值