栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C实现单链表

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C实现单链表

目录

1.单链表的概念

2.单链表的实现

2.1头文件

2.2test.c文件

2.3单链表增删查改的实现

3.总结   


1.单链表的概念

那么什么是链表呢?其实链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。简单来说就是自己定义了一个结构体构体,结构体里面有多个对象,其中常见的包括存储数据对象和结构体类型地址,(其实就是套娃,只要下一个结构体地址开辟完成后,让上一个在结构体对象里的结构体地址与刚开辟好的新节点地址相同就能实现单链表的连接)。

    无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。
    带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。下面我们来实现单链表。

2.单链表的实现

2.1头文件
#pragma once
#include
#include
#include
typedef int DataType;

typedef struct Slist {
	struct Slist* next;
	DataType data;
}Slist;



SlistPushBack(Slist**ps, DataType x);
Slistprint(Slist*ps);
SlistDestroy(Slist**ps);
SlistPopBack(Slist**ps);
SlistPushFront(Slist** ps, DataType x);
SlistPopFront(Slist**ps);
Slist*SlistFind(Slist*ps, DataType x);
SlistInsert(Slist*pos, DataType x);

2.2test.c文件
void SlistTest2()
{
	Slist* phead = NULL;
	SlistPushBack(&phead, 1);
	SlistPushBack(&phead, 2);
	SlistPushBack(&phead, 3);

	Slistprint(phead);

	SlistPopBack(&phead);
	SlistPopBack(&phead);
	SlistPopBack(&phead);

	Slistprint(phead);

	SlistPushFront(&phead,11);
	SlistPushFront(&phead, 12);
	SlistPushFront(&phead, 13);

	Slistprint(phead);

	SlistPopFront(&phead);
	SlistPopFront(&phead);

	Slistprint(phead);

	Slist* pos = SlistFind(phead, 11);
	//在pos位置后面加入
	SlistInsert(pos, 100);
	Slistprint(phead);

	SlistDestroy(&phead);
}

int main()
{
	//1.顺序表测试
	//SlistTest1();
	//2.单链表测试
	SlistTest2();

	return 0;
}

2.3单链表增删查改的实现

比较简单,不详细讨论,只想自己复习一下。

#include"Slist.h"

Slist* BuyNode(DataType x)
{
	Slist* tmp = (Slist*)malloc(sizeof(Slist));
	if (tmp == NULL)
	{
		printf("空间开辟失败n");
		exit(-1);
	}
	else {
		tmp->data = x;
		tmp->next = NULL;
	}
	return tmp;
}

SlistPushBack(Slist** ps, DataType x)
{
	assert(ps);
	Slist* newnode = BuyNode(x);
	Slist* findtail = *ps;
	if (*ps == NULL)
	{
		*ps = newnode;
	}
	else {
		while (findtail->next!=NULL)
		{
			findtail = findtail->next;
		}
	   findtail->next = newnode;
	}
}


Slistprint(Slist* ps)
{
	Slist* cur = ps;
	while (cur)
	{
		printf("%d ", cur->data);
		cur = cur->next;
	}
	printf("n");
}

SlistDestroy(Slist** ps)
{
	assert(ps);
	Slist* cur = *ps;
	while (cur)
	{
		Slist* next =cur->next;
		free(cur);
		cur = next;
	}
	*ps = NULL;
}

SlistPopBack(Slist** ps)
{
	assert(ps);
	
	if (*ps == NULL)
	{
		return 1;
	}
	else if((*ps)->next==NULL)
	{
		free(*ps);
		*ps = NULL;
	}
	else
	{
		Slist* tail = *ps;
		Slist* prve = NULL;
		while (tail->next!=NULL)
		{
			prve = tail;
			tail = tail->next;
		}
		free(tail);
		tail = NULL;
		prve->next = NULL;

	}
	Slist* cur = *ps;

}

SlistPushFront(Slist** ps, DataType x)
{
	assert(ps);
	if (*ps == NULL)
	{
		Slist* newnode = BuyNode(x);
		*ps = newnode;
	}
	else {
		Slist* newnode = BuyNode(x);
		newnode->next = *ps;
		*ps = newnode;
	}

}

SlistPopFront(Slist** ps)
{
	assert(ps);
	if (*ps == NULL)
	{
		return 0;
	}
	else if ((*ps)->next == NULL)
	{
		free(*ps);
			* ps = NULL;
	}
	else {
		Slist* next = (*ps)->next;
		free(*ps);
		*ps = next;
	}
}

Slist* SlistFind(Slist* ps, DataType x)
{
	Slist* cur = ps;
	while (cur)
	{
		if (cur->data == x)
			return cur;
		cur = cur->next;
	}
	return NULL;
}

SlistInsert( Slist* pos, DataType x)
{
   assert(pos);
	Slist* newnode = BuyNode(x);
	Slist* next = pos->next;
	pos->next = newnode;
	newnode->next = next;
}


3.总结   

单链表结构,适合头插头删。尾部或者中间某个位置插入删除不适合。
如果要使用链表单独存储数据,带头双向链表更合适,单链表的使用一般都结合图的邻接表,哈希桶这些。。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/879570.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号