当前位置: 代码网 > it编程>编程语言>C/C++ > 实现链表的增删查改

实现链表的增删查改

2024年07月28日 C/C++ 我要评论
在链表的实现中,也要注意指针释放时,能否还能找到被释放的指针指向的下一个元素,因此我们通常还得设置一个prev指针,假如pos为想要删去的位置,我们要在pre->next!将prev->next = pos->next,防止pos释放后找不到pos的下一个节点。最后,完成一个链表的实现最重要的就是画图,多画图就知道如何实现一个链表的增删查改的一个思路了。这里链表在涉及到头指针的删除与改变时,我们要传二级指针,因为我们要传头指针的地址,才能改变头指针的值。我们再来看一张图,明白指针,二级指针表明的是什么。
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int sltdatatype;
typedef struct slistnode
{ 
	sltdatatype data;
	struct slistnode* next;
}sltnode;

void sltprint(sltnode* phead);

//尾插
void sltpushback(sltnode** phead, sltdatatype x);
//头插
void sltpushfront(sltnode** pphead, sltdatatype x);
//尾删
void sltpopback(sltnode** pphead);
void sltpopfront(sltnode** pphead);
sltnode* sltfind(sltnode* phead, sltdatatype x);
//在指定位置之前插入数据
void sltinsert(sltnode** pphead, sltnode* pos, sltdatatype x);
void sltinsertafter(sltnode* pos, sltdatatype x);
void slterase(sltnode** phead, sltnode* pos);
void slteraseafter(sltnode* pos);
void slistdestroy(sltnode** pphead);


#include"slist.h"

void sltprint(sltnode* phead)
{
	sltnode* pcur = phead;
	while (pcur)
	{
		printf("%d->", pcur->data);
		pcur = pcur->next;
	}
	printf("null\n");
}

sltnode* sltbuynode(sltdatatype x)
{
	sltnode* newnode = (sltnode*)malloc(sizeof(sltnode));
	if (newnode == null)
	{
		perror("malloc fail!");
		exit(1);
	}
	newnode->data = x;
	newnode->next = null;

	return newnode;
}
void sltpushback(sltnode** pphead, sltdatatype x)
{	
	//空链表和非空链表
	sltnode* newnode = sltbuynode(x);
	if (*pphead == null)
	{
		*pphead = newnode;
	}
	else
	{
		sltnode* ptail = *pphead;
		while (ptail->next)
		{
			ptail = ptail->next;
		}
		ptail->next = newnode;
	}
}

void sltpushfront(sltnode** pphead, sltdatatype x)
{	
	assert(pphead);
	sltnode* newnode = sltbuynode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}

void sltpopback(sltnode** pphead)
{
	assert(pphead);
	//链表不能为空
	assert(*pphead);
	sltnode* prev = *pphead;
	sltnode* ptail = *pphead;
	while (ptail->next)
	{
		prev = ptail;
		ptail = ptail->next;
	}
	free(ptail);
	ptail = null;
	prev->next = null;
}
void sltpopfront(sltnode** pphead)
{
	assert(pphead && *pphead);
	sltnode* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;
}

sltnode* sltfind(sltnode* phead, sltdatatype x)
{
	sltnode* pcur = phead;
	while (pcur)
	{
		if (pcur->data == x)
		{
			return pcur;
		}
		pcur = pcur->next;
	}
	return null;
}

void sltinsert(sltnode** pphead, sltnode* pos, sltdatatype x)
{
	assert(*pphead && pphead);
	assert(pos);
	sltnode* newnode = sltbuynode(x); 
	//若pos == *pphead
	if (pos == *pphead)
	{
		sltpushfront(pphead, x);
	}
	sltnode* prev = *pphead;
	while (prev->next)
	{
		prev = prev->next;
	}
	newnode->next = pos;
	prev->next = newnode;
}

void sltinsertafter(sltnode* pos, sltdatatype x)
{
	assert(pos);
	sltnode* newnode = sltbuynode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

void slterase(sltnode** pphead, sltnode* pos)
{
	assert(pphead && *pphead);
	assert(pos);
	if (pos == *pphead)
	{
		sltpopfront(pphead);//头删是要传二级指针

	}

	sltnode* prev = *pphead;
	while(prev->next != pos)
	{
		prev = prev->next;
	}
	prev->next = pos->next;
	free(pos);
	pos = null;
}

void slteraseafter(sltnode* pos)
{
	assert(pos&&pos->next);
	sltnode* del = pos->next;
	pos->next = del->next;
	free(del);
	del = null;
}

void slistdestroy(sltnode** pphead)
{
	sltnode* pcur = *pphead;
	while (pcur)
	{
		while (pcur)
		{
			sltnode* next = pcur->next;
			free(pcur);
			pcur = null;
		}
	}
	*pphead = null;
}
#include"slist.h"

void slisttest01()
{	
	//创建几个节点


	sltnode* node1 = (sltnode*)malloc(sizeof(sltnode));
	node1->data = 1;

	sltnode* node2 = (sltnode*)malloc(sizeof(sltnode));
	node2->data = 2;

	sltnode* node3 = (sltnode*)malloc(sizeof(sltnode));
	node3->data = 3;

	sltnode* node4 = (sltnode*)malloc(sizeof(sltnode));
	node4->data = 4;

	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = null;

	sltpushback(node4, 6);
	sltnode* plist = node1;
	sltprint(plist);


}

void slisttest02()
{
	sltnode* plist = null;
	sltpushback(&plist, 1);
	sltpushback(&plist, 2);
	sltpushback(&plist, 3);
	sltpushback(&plist, 4);
	sltpushfront(&plist, 5);
	sltpushfront(&plist, 6);
	sltprint(plist);

	sltpopback(&plist);//相当于尾删了一个4
	sltprint(plist);

	sltnode* find = sltfind(plist, 3);
	//sltinsert(&plist, find, 11);//在find位置之前插入11;
	sltinsertafter(find, 11);
	sltprint(plist);

	slterase(&plist, find);
	sltprint(plist);

	slistdestroy(&plist);
	sltprint(plist);
	

//	if (find == null)
//	{
//		printf("没有找到");
//	}
//	else
//	{
//		printf("找到了");
//	}
}

int main()
{
	/*slisttest01();*/
	slisttest02();
	return 0;
}

        最后,完成一个链表的实现最重要的就是画图,多画图就知道如何实现一个链表的增删查改的一个思路了。最后,愿大家大学不挂科,写代码超级神!!!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com