C语言数据结构-----单链表(无头单向不循环)

前言

本篇讲述了单链表的相关知识,以及单链表增删查改的代码实现。


1.链表

1.1 链表的结构和概念

概念如下: 链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。

结构如下:
在这里插入图片描述

用代码可以这样表示:

struct SListNode
{
    
    
 	int val;
 	struct SListNode* next;
};

但是不属于结构体嵌套结构体!!!!!

2.(增删查改)单链表的实现

这里只展示自定义函数部分,查看完整代码可以进入我的gitee拷贝。
链接: 完整代码点这里

2.1 打印链表

void SLTPrint(SLNode* phead)
{
    
    
	SLNode* cur = phead;
	while (cur != NULL)
	{
    
    
		printf("%d ", cur->val);
		cur = cur->next;
	}
	printf("NULL\n");
}

2.2 尾插

void SLTPushBack(SLNode** pphead, SLNDataType x)
{
    
    
	SLNode* newnode = CreateNode(x);

	if (*pphead == NULL)
	{
    
    
		*pphead = newnode;
	}
	else
	{
    
    
		// 找尾
		SLNode* tail = *pphead;
		while (tail->next != NULL)
		{
    
    
			tail = tail->next;
		}

		tail->next = newnode;
	}
}

在这里插入图片描述

2.3 尾删

void SLTPopBack(SLNode** pphead)
{
    
    
	assert(*pphead);

	// 1、一个节点
	// 2、一个以上节点
	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;
	}
}

在这里插入图片描述

2.4 头插

void SLTPushFront(SLNode** pphead, SLNDataType x)
{
    
    
	SLNode* newnode = CreateNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}

在这里插入图片描述

2.5 头删

void SLTPopFront(SLNode** pphead)
{
    
    
	assert(*pphead);

	// 一个以上节点 + 一个
	SLNode* tmp = *pphead;
	*pphead = (*pphead)->next;
	free(tmp);
}

在这里插入图片描述

2.6 查找

SLNode* SLTFind(SLNode* phead, SLNDataType x)
{
    
    
	SLNode* cur = phead;
	while (cur != NULL)
	{
    
    
		if (cur->val == x)
		{
    
    
			return cur;
		}
		else
		{
    
    
			cur = cur->next;
		}
	}
	return NULL;
}

2.7 在指定位置(pos)前插入

void SLTInsertpre(SLNode** pphead, SLNode* pos, SLNDataType x)
{
    
    
	// 严格限定pos一定是链表里面的一个有效节点
	assert(pphead);
	assert(pos);
	assert(*pphead);

	if (*pphead == pos)
	{
    
    
		// 头插
		SLTPushFront(pphead, x);
	}
	else
	{
    
    
		SLNode* prev = *pphead;
		while (prev->next != pos)
		{
    
    
			prev = prev->next;
		}

		SLNode* newnode = CreateNode(x);
		prev->next = newnode;
		newnode->next = pos;
	}
}

在这里插入图片描述

2.8 在指定位置(pos)删除

void SLTErasepre(SLNode** pphead, SLNode* pos)
{
    
    
	assert(pphead);
	assert(*pphead);
	assert(pos);

	if (*pphead == pos)
	{
    
    
		// 头删
		SLTPopFront(pphead);
	}
	else
	{
    
    
		SLNode* prev = *pphead;
		while (prev->next != pos)
		{
    
    
			prev = prev->next;
		}

		prev->next = pos->next;
		free(pos);
		pos = NULL;
	}
}

在这里插入图片描述

2.9 在指定位置(pos)后插入

void SLTInsertAfter(SLNode* pos, SLNDataType x)
{
    
    
	assert(pos);
	SLNode* newnode = CreateNode(x);

	newnode->next = pos->next;
	pos->next = newnode;
}

在这里插入图片描述

2.10 在指定位置(pos)后删除

void SLTEraseAfter(SLNode* pos)
{
    
    
	assert(pos);
	assert(pos->next);

	SLNode* tmp = pos->next;
	pos->next = pos->next->next;

	free(tmp);
	tmp = NULL;
}

在这里插入图片描述

2.11 摧毁链表

void SLTDestroy(SLNode** pphead)
{
    
    
	assert(pphead);

	SLNode* cur = *pphead;
	while (cur)
	{
    
    
		SLNode* next = cur->next;
		free(cur);
		cur = next;
	}
	*pphead = NULL;
}

在这里插入图片描述
链接: 完整代码点这里

猜你喜欢

转载自blog.csdn.net/qq_57425280/article/details/134138758