C语言之链表

文章目录

前言

一、链表基本概念

1、声明节点结构

2、创建节点变量

3、链表所有节点

4、遍历链表

二、add添加

三、insert插入

四、remove删除

五、查找

总结


前言

链表是一种重要的数据结构,用于存储和组织数据。它是由一系列节点组成的数据结构,每个节点包含一个数据元素和一个指向下一个节点的指针。链表相比于数组具有更灵活的插入和删除操作,但访问元素的效率较低。在本文中,我们将学习如何使用C语言实现链表,包括创建节点、插入数据、删除数据等操作。通过学习链表的实现和应用,我们可以更好地理解数据结构的设计和算法的应用。


一、链表基本概念

1、声明节点结构

cpp 复制代码
typedef struct node
{
	int data;//数据域
	struct node * next;//下一个节点
} Node, *P_NODE;

2、创建节点变量

n1、n2、n3、n4、n5都存储在栈区。

使用malloc在内存中申请空间,存储在堆区。

cpp 复制代码
    Node n1 = { 5,NULL };
	Node n2 = { 10,NULL };
	Node n3 = { 9,NULL };
	Node n4 = { 3,NULL };
	Node n5 = { 8,NULL };*/
	Node *p1 = malloc(sizeof(struct node));
	p1->next = NULL;
	p1->data = 5;
	Node* p2 = malloc(sizeof(struct node));
	p2->next = NULL;
	p2->data = 10;
	Node* p3 = malloc(sizeof(struct node));
	p3->next = NULL;
	p3->data = 9;
	Node* p4 = malloc(sizeof(struct node));
	p4->next = NULL;
	p4->data = 3;
	Node* p5 = malloc(sizeof(struct node));
	p5->next = NULL;
	p5->data = 8;

3、链表所有节点

将链表通过next的指向连接起来。

cpp 复制代码
	n1.next = &n2;
	n2.next = &n3;
	n3.next = &n4;
	n4.next = &n5;

	p1->next = p2;
	p2->next = p3;
	p3->next = p4;
	p4->next = p5;

4、遍历链表

cpp 复制代码
#include <stdio.h>
#include <malloc.h>

int main()
{
	//Node* p = &n1;
	Node* p = p1;
	while (p)
	{
		printf("%d\n",p->data);
		p = p->next;
	}


	return 0;
}

二、add添加

声明了头结点和尾节点指向了空,定义了一个创建节点的函数和往尾部添加节点的函数。

cpp 复制代码
#include<stdio.h>
#include <stdlib.h>
#include"link.h"

PNode header = NULL;
PNode ender = NULL;
int main()
{
	PNode p = create(5);
	add(p);
	add(create(10));
	add(create(9));
	add(create(3));
	add(create(8));
	return 0;
}
PNode create(int data)
{
	Node* newNode = malloc(sizeof(struct node));
	newNode->data = data;
	newNode->next = NULL;
	return newNode;
}

void add(PNode node)
{
	if (header==NULL)
	{
		header = ender = node;
	}
	else
	{
		ender->next = node;
		ender = node;
	}
		 
}

三、insert插入

该实例的插入实现的是中间插入。

代码主要实现了一个链表的创建、节点添加以及在指定位置之后插入新节点的功能。具体步骤为:先创建一个链表,向链表中添加若干节点,然后在指定索引位置的节点之后插入一个新节点。

代码详细解释

cpp 复制代码
#include<stdio.h>
#include <stdlib.h>
#include"link.h"

int main ()
{
	//测试用例
	PNode p = create(5);
	add(p);
	add(create(10));
	add(create(9));

	add(create(3));
	add(create(9));
	insert_behind(2,create(666));


	return 0;
} 
/*中间插入*/
void insert_behind(int index, PNode node)
{ 
	PNode p = header;
	for (int i=0;i<index;i++)
	{
		p = p->next;
	}
	PNode q = p->next;
	node->next = q;
	p->next = node;

}


 

四、remove删除

主要实现了一个链表的操作,包括创建链表节点、向链表中添加节点、根据索引删除节点以及根据节点数据删除节点等功能。

代码的主要目的是构建一个链表,并对链表进行节点的添加和删除操作。具体来说,它创建了一个包含多个节点的链表,然后根据节点的数据值删除链表中所有值为 9 的节点。

cpp 复制代码
#include<stdio.h>
 #include <stdlib.h>
#include"link.h"
 
int main04()
{
	PNode p = create(5);
	add(p);
	add(create(10));
	add(create(9));

	add(create(3));
	add(create(9));
	//remove_index(2);
	remove_data(9);
	return 0;
}
void remove_index(int index)
{
	PNode p = header;
	PNode q = NULL;
	for (int i=0;i<index;i++)
	{
		q = p;
		p = p->next;
	 }
	PNode m=p->next;
	q->next = m;
	free(p);
	p = NULL;
}

void remove_data(int data) 
{
	/*PNode p = header;
	PNode q = NULL;
	while (p->data!=data)
	{
		q = p;
		p = p->next;
	}
	PNode m = p->next;
	q->next = m;
	free(p);
	p = NULL;*/

	int xb = indexOf(data);
	if (xb>=0)
	{
		remove_index(xb);
	}
	
}

五、查找

代码实现了一个简单链表的基本操作,包括创建节点、添加节点、删除节点、获取链表长度、根据索引获取节点、查找特定值节点的索引等功能。

cpp 复制代码
#include<stdio.h>
#include"link.h"
#include <stdlib.h>
 

int main()
{
	PNode p = create(5);
	add(p);
	add(create(10));
	add(create(9));

	add(create(3));
	add(create(99));
	add(create(999));
	add(create(9999));
	remove_data(99);
	int len = size();
	for (int i=0;i<len;i++)
	{
		PNode p = get(i);
		printf("%d\n",p->data);
	}
	printf("999:%d\n", indexOf(999));
	printf("666:%d\n", indexOf(666));
	return 0;
}
int size()
{
	int count = 0;
	PNode p = header;
	while (p)
	{
		count++;
		p = p->next;
	}
	return count;
}
PNode get(int index)
{
	PNode p = header;
	for (int i = 0; i < index; i++)
	{
		p = p->next;
	}
	return p;
}

int indexOf(int data)
{
	PNode p = header;
	for (int i=0;p!=NULL;i++)
	{
	if (p->data == data)
		{
			return i;
		}
		p = p->next;
	}
	return -1;
}

总结

链表是一种常见的数据结构,用于存储一系列元素。在C语言中,链表通常由节点(Node)组成,每个节点包含元素值和指向下一个节点的指针。链表可以分为单向链表、双向链表和循环链表等不同类型。

常见的链表操作包括插入、删除、查找等。插入操作包括在链表头部、尾部或指定位置插入节点;删除操作包括删除指定位置或特定值的节点;查找操作可以遍历链表寻找指定值的节点。

链表相较于数组的优势在于动态插入和删除操作效率高,不需要提前知道数据量大小。但链表的缺点是查找特定元素的效率较低,需要遍历整个链表。

在实现链表时,需要注意内存管理,确保在释放节点时不会造成内存泄漏。同时,链表的结构设计也需要考虑头节点、尾节点、空链表等特殊情况的处理。

总的来说,链表是一种灵活且常用的数据结构,在实际应用中被广泛使用。熟练掌握链表的操作和实现方式对于提高程序效率和解决问题都具有重要意义。

相关推荐
芯片SIPI设计6 分钟前
MIPI C-PHY 标准学习----一种通用多信号传输方案
c语言·开发语言·学习
Tiny番茄17 分钟前
No module named ‘xxx’报错原因及解决方式
开发语言·python
咩咩觉主32 分钟前
c#数据结构 线性表篇 非常用线性集合总结
开发语言·数据结构·unity·c#·游戏引擎·程序框架
李匠20241 小时前
C++GO语言微服务和服务发现②
开发语言·c++·golang·服务发现
每次的天空1 小时前
Kotlin 内联函数深度解析:从源码到实践优化
android·开发语言·kotlin
268572591 小时前
JVM 监控
java·开发语言·jvm
曼岛_1 小时前
[Java实战]Spring Boot 静态资源配置(十三)
java·开发语言·spring boot
m0_616188491 小时前
使用vue3-seamless-scroll实现列表自动滚动播放
开发语言·javascript·ecmascript
qq_433554542 小时前
C++ STL编程 vector空间预留、vector高效删除、vector数据排序、vector代码练习
开发语言·c++
XiaoCCCcCCccCcccC2 小时前
Linux网络基础 -- 局域网,广域网,网络协议,网络传输的基本流程,端口号,网络字节序
linux·c语言·网络·c++·网络协议