线性表-单链表(含完整C代码)

咱们继续——单向链表。

目录

1.链表

1.1链表的诞生

1.2链式存储结构

1.3.分类

2.单向链表

2.1概念

2.2头指针和头结点

2.3操作

2.4完整代码


1.链表

1.1链表的诞生

学完顺序表后,我们了解到数组作为存储结构有一定的缺点:

  • 无序数组:搜索十分低效
  • 有序数组:插入十分低效
  • 两种数组:删除都很低效,且大小无法改变

为了解决顺序表的缺陷,链表就此诞⽣,链表也是继数组之后第⼆种使⽤的最⼴泛的通⽤数据结构。

1.2链式存储结构

1.概念:用指针将相互关联的结点链接起来。

2.特点

  • 物理上不连续,逻辑上连续
  • 大小不固定
  • 基于指针实现
  • 结点=数据域+指针域

1.3.分类

  • 单向链表
  • 单向循环链表
  • 双向链表
  • 双向循环链表

2.单向链表

2.1概念

单向链表的每个结点只包含⼀个指针域,即构成链表的每个结点只有⼀个指向后继节点的指针。

2.2头指针和头结点

1.单链表有带头结点和不带头结点两种结构。

2.第⼀个结点存储的位置叫头指针。如果链表有头结点,那么头指针就是指向头结点的指针。

3.头指针所指的不存数据元素的第⼀个结点就叫做头结点,头结点又指向⾸元结点。头结点⼀般不放数据(有时也放链表的⻓度,用做监视)。

4.存放第⼀个数据元素的结点叫作首元结点。

2.3操作

以带头结点的单向链表举例元素的插入(头插+中间插入)与删除。

1.头插法

在头结点后插入新的结点。需要先给插入结点的指针赋值,再改变头结点指针,使其指向插入结点,两者顺序不可颠倒

头插法流程

/*头插法*/
//在头结点后,其他结点前插入元素
//node:头结点,n:待插入元素,insert:待插入结点
void HeadInsert(Link* node, int n)
{
	Link* insert = (Link*)malloc(sizeof(Link));
	insert->data = n;
	insert->next = node->next;
	node->next = insert;
}

 2.中间插入

在中间位置插入结点。插入逻辑同头插法,但需要一个临时指针temp指向插入位置的前一个结点(通过循环实现),而不移动头指针。

中间插入流程
void MidInsert(Link* node, int n, int i)
{
	Link* insert = (Link*)malloc(sizeof(Link));
	Link* temp = (Link*)malloc(sizeof(Link));
	temp = node->next;

	//将temp指向插入位置后的元素
	int j = 0;
	while (temp != NULL && j < i - 1)
	{
		temp = temp->next;
		j++;
	}
	if (temp == NULL && i > j - 1)
		printf("没有此位置,插入失败\n");

	insert->data = n;
	insert->next = temp->next;
	temp->next = insert;
}

 3.删除

删除结点在中间位置时,同样需要一个临时指针temp,原因同上。先保存要删除的结点,将删除结点的前一个结点指针指向删除结点的后一个结点,然后释放待删除结点。

删除流程

* 将图左上方“中间插入”改为“删除”

/*删除元素*/
void delete(Link* node, int n)
{
	Link* temp = (Link*)malloc(sizeof(Link));
	temp = node->next;
	//找到删除元素下标,并把temp指向要删除结点的前一个结点
	int i = find(node, n);
	if (i == -1)
		printf("没有此元素,删除失败\n");
	else
	{
		int j = 0;
		while (j < i - 1)
		{
			temp = temp->next;
			j++;
		}
		//先保存要删除的结点,再改变指针指向
		Link* FreeNode = temp->next;
		temp->next = temp->next->next;
		free(FreeNode);
	}
}

2.4完整代码

完整C语言代码嗷~

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

typedef struct LinkList
{
	int data;//数据域
	struct LinkList* next;//指针域
}Link;

Link* InitList();
void HeadInsert(Link* node, int n);
void MidInsert(Link* node, int n, int i);
int find(Link* node, int n);
void delete(Link* node, int n);
void show(Link* node);

int main()
{
	Link* node = InitList();
	HeadInsert(node, 1);
	HeadInsert(node, 2);
	HeadInsert(node, 3);
	HeadInsert(node, 4);
	show(node);//输出4321
	printf("\n");

	MidInsert(node, 5, 1);
	show(node);//输出45321
	printf("\n");

	int i = find(node, 2);
	printf("%d\n", i);//输出3

	delete(node, 3);
	show(node);//输出4521

	return 0;
}

/*初始化单链表*/
//创建一个头结点
Link* InitList()
{
	Link* node = (Link*)malloc(sizeof(Link));
	if (node == NULL)
		printf("初始化函数已执行,内存分配失败\n");
	else
		node->next = NULL;
	return node;
}

/*头插法*/
//在头结点后,其他结点前插入元素
//node:头结点,n:待插入元素,insert:待插入结点
void HeadInsert(Link* node, int n)
{
	Link* insert = (Link*)malloc(sizeof(Link));
	insert->data = n;
	insert->next = node->next;
	node->next = insert;
}

/*中间插入*/
//在第i个位置前插入一个元素n
//temp:临时指针,用于移动找位置,而不用移动头指针
void MidInsert(Link* node, int n, int i)
{
	Link* insert = (Link*)malloc(sizeof(Link));
	Link* temp = (Link*)malloc(sizeof(Link));
	temp = node->next;

	//将temp指向插入位置后的元素
	int j = 0;
	while (temp != NULL && j < i - 1)
	{
		temp = temp->next;
		j++;
	}
	if (temp == NULL && i > j - 1)
		printf("没有此位置,插入失败\n");

	insert->data = n;
	insert->next = temp->next;
	temp->next = insert;
}

/*查找元素*/
//temp一直挨个向后移动,若发现有,则返回下标,直到指向空
int find(Link* node, int n)
{
	Link* temp = (Link*)malloc(sizeof(Link));
	temp = node->next;

	int i = 0;
	while (temp != NULL)
	{
		if (temp->data == n)
			return i;
		else
		{
			temp = temp->next;
			i++;
		}
	}
	return -1;
}

/*删除元素*/
void delete(Link* node, int n)
{
	Link* temp = (Link*)malloc(sizeof(Link));
	temp = node->next;
	//找到删除元素下标,并把temp指向要删除结点的前一个结点
	int i = find(node, n);
	if (i == -1)
		printf("没有此元素,删除失败\n");
	else
	{
		int j = 0;
		while (j < i - 1)
		{
			temp = temp->next;
			j++;
		}
		//先保存要删除的结点,再改变指针指向
		Link* FreeNode = temp->next;
		temp->next = temp->next->next;
		free(FreeNode);
	}
}

/*展示数据元素*/
void show(Link* node)
{
	Link* temp = (Link*)malloc(sizeof(Link));
	temp = node->next;
	while (temp != NULL)
	{
		printf("%d", temp->data);
		temp = temp->next;
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~在下小吴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值