单链表的实现

本篇文章教你如何实现单链表操作。

目录

结构体定义 

节点创建

 尾插

头插 

 尾删

头删 

查找 

pos位置前插入 

pos位置后插入 

删除pos位置 

销毁链表

打印链表 

 


结构体定义 

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

节点创建

 首先分配空间,然后检查节点是否创建成功,最后进行赋值。

//创建节点
SListNode* CreateNode(SListData x)
{
	SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
	if (newnode == NULL)//检查是否为空
	{
		perror("malloc:");
		exit(-1);
	}
	newnode->next = NULL;
	newnode->val = x;
	return newnode;
}

 尾插

尾插操作两种情况:链表为空,直接覆盖头节点,链表不为空,先找尾,再插入。

因为可能要改变头节点地址,所以传二级指针

void PushBack(SListNode** head, SListData x)
{
	assert(head);
	SListNode* newnode = CreateNode(x);
	if (*head == NULL)//链表为空
	{
		*head = newnode;
	}
	else
	{
		SListNode* tail = *head;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}

头插 

头插分两种情况:链表为空,链表不为空。

//头插
void PushFront(SListNode** head, SListData x)
{
	assert(head);
	SListNode* newnode = CreateNode(x);
	if (*head == NULL)//链表为空
	{
		*head = newnode;
	}
	else
	{
		newnode->next = *head;
		*head = newnode;
	}
}

 尾删

尾删分三种情况:1.链表为空,不能进行删除。 2.只有一个元素,相当于头删 3.多个元素,

要找到尾,并保留尾前一个位置。

//尾删
void PopBack(SListNode** head)
{
	assert(head);
	assert(*head);//链表为空
	if ((*head)->next== NULL)//1个节点
	{
		free(*head);
		*head = NULL;
	}
	else
	{//多个节点
		SListNode* cur = *head;
		while (cur->next->next != NULL)
		{
			cur = cur->next;
		}
		free(cur->next);
		cur->next = NULL;
	}
}

头删 

头删要检查链表是否为空。

void PopFront(SListNode** head)
{
	assert(head);
	assert(*head);
	SListNode* next = (*head)->next;
	free(*head);
	*head = next;
}

查找 

 找到返回节点地址,未找到返回空。

SListNode* Find(SListNode* head, SListData x) 
{
	assert(head);
	while (head != NULL)
	{
		if (head->val == x)
		{
			return head;
		}
		head = head->next;
	}
	return NULL;//没找到返回空
}

pos位置前插入 

插入操作要确保此位置存在!

//在pos位置之前插入
void Insert(SListNode** head, SListNode* pos, SListData x)
{
	assert(head);
    assert(pos);检查pos
	if (*head == pos)
	{
		PushFront(head, x);
	}
	else
	{
		SListNode* newnode = CreateNode(x);
		SListNode* cur = *head;
		while (cur&&cur->next!= pos)//检查pos是否在链表中
		{
			cur = cur->next;
		}
		if (cur == NULL)
		{
			printf("没有当前位置,无法插入");
			exit(-1);
		}
		cur->next = newnode;
		newnode->next = pos;
	}
}

pos位置后插入 

检查pos位置是否在链表中!

//在pos位置后插入
void InsertAfter(SListNode** head, SListNode* pos, SListData x)
{
	assert(head);
    assert(pos);//检查pos
	SListNode* newnode = CreateNode(x);
	SListNode* cur = *head;
	while (cur && cur->next != pos)
	{
		cur = cur->next;
	}
	if (cur == NULL)
	{
		printf("链表无当前位置,无法插入");
		exit(-1);
	}
	newnode->next = pos->next;
	pos->next = newnode;
}

删除pos位置 

检查pos!

//删除pos位置
void Erase(SListNode** head,SListNode*pos)
{
	assert(head);
	assert(pos);
	if (*head == pos)
	{
		PopFront(head);
	}
	else
	{
		SListNode* cur = *head;
		while (cur && cur->next != pos)
		{
			cur = cur->next;
		}
		if (cur == NULL)
		{
			printf("链表无当前位置,无法插入");
			exit(-1);
		}
		cur->next = pos->next;
		free(pos);
		pos = NULL;//位置删除后,指向改位置的指针置空
	}
}

销毁链表

//销毁链表
void Destory(SListNode** head)
{
	assert(head);
	SListNode* cur = *head;
	SListNode* next = NULL;
	while (cur != NULL)
	{
		next = cur->next;
		free(cur);
		cur = next;
	}
	*head = NULL;//注意头节点要置空
}

打印链表 

void Print(SListNode* head)
{
	assert(head);
	while (head != NULL)
	{
		printf("%d ", head->val);
		head = head->next;
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

嚞譶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值