C语言:结构体中链表的添加与删除

C语言中的链表作为一个重要的知识点,我觉得在进行链表的相关操作时首先要理解链表分三种,单向链表、双向链表、循环链表。

虽然说是三种,但其实本质都是一样的,就是在一个结构体里面有数据域和指针域,数据域中用来描述节点的信息,而指针域中用来指向上一个节点或者下一个节点。

分为按值添加和按位置添加

说明:

此添加、删除为按值添加、删除

下面请看代码:

添加分为链表中头节点的插入

在中间插入

尾插入

删除也分为头删除

中间删除

尾删除

一些细节上的处理:

传参时,如果要改变头节点,就传二级指针,不需要改变头节点,就传一级指针

 单链表中有很多函数都需要分类导论,要考虑它只有一个节点或没有节点的极端情况

注意在不需要改变头节点时,万万不能随便解引用头节点以及连续写两个->next时,因为这种情况下很容易出现问题

#include <stdio.h>
#include <stdlib.h>

typedef struct Node
{
	int id;
	char* name;
	struct Node* pNext;
}List;
void AddNode(List** pphead, List** ppend, int id, char* name)
{
	List* ptemp =(List*) malloc(sizeof(List));
	ptemp->id = id;
	ptemp->name = name;
	ptemp->pNext = NULL;
	if (*pphead == NULL)
	{
		*pphead = ptemp;
	}
	else
	{
		(*ppend)->pNext = ptemp;
	}
	*ppend = ptemp;
}
void InsertNode(List** pphead, List** ppend, List* pNode, int n)
{
	List* pmark = *pphead;
	if ((*pphead)->id == n)
	{
		pNode->pNext = *pphead;
		*pphead = pNode;
	}
	while (pmark != *ppend)
	{
		if (pmark->pNext->id == n)
		{
			pNode->pNext = pmark->pNext;
			pmark->pNext = pNode;
			return;
		}
		pmark = pmark->pNext;
	}
	(*ppend)->pNext = pNode;
	*ppend = pNode;
}
void DeletNode(List** pphead, List** ppend, int n)
{
	List* pDel = NULL;
	List* pmark = *pphead;
	if ((*pphead)->id == n)
	{
		pDel = *pphead;
		(*pphead) = (*pphead)->pNext;
		free(pDel);
		pDel = NULL;
		return;
	}
	while (pmark != (*ppend))
	{
		if (pmark->pNext->id == n)
		{
			pDel = pmark->pNext;
			pmark->pNext = pDel->pNext;
			free(pDel);
			pDel = NULL;
			if (pmark->pNext == NULL)
			{
				*ppend = pmark;
			}
			return;
		}
		pmark = pmark->pNext;
	}
}
int main()
{
	List* phead = NULL;
	List* pend = NULL;
	AddNode(&phead, &pend, 1, "aa");
	AddNode(&phead, &pend, 2, "bb");
	AddNode(&phead, &pend, 3, "cc");
	AddNode(&phead, &pend, 4, "dd");
	AddNode(&phead, &pend, 5, "ee");

	List* p =(List*) malloc(sizeof(List));
	p->id = 7;
	p->name = "gg";
	p->pNext = NULL;
	/*InsertNode(&phead, &pend, p, 9);*/
	DeletNode(&phead, &pend, 5);

	while (phead != NULL)
	{
		printf("%d    %s\n", phead->id, phead->name);
		phead = phead->pNext;
	}
	return 0;
}

输出:

1    aa
2    bb
3    cc
4    dd

D:\c++\c语言\结构体 链表\x64\Debug\结构体 链表.exe (进程 15672)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .



总结:

链表和数组作为算法中的两个基本数据结构,在程序设计过程中经常用到。尽管两种结构都可以用来存储一系列的数据,但又各有各的特点。

数组的优势,在于可以方便的遍历查找需要的数据。在查询数组指定位置(如查询数组中的第4个数据)的操作中,只需要进行1次操作即可,时间复杂度为O(1)。但是,这种时间上的便利性,是因为数组在内存中占用了连续的空间,在进行类似的查找或者遍历时,本质是指针在内存中的定向偏移。然而,当需要对数组成员进行添加和删除的操作时,数组内完成这类操作的时间复杂度则变成了O(n)。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值