【数据结构】(C语言):链表

链表:

  • 基本单位是节点。节点至少两部分:数据,下一个数据的地址。
  • 头指针head,始终指向链表的第一个节点。若没有节点,则head=NULL。
  • 链表在内存中是非连续的。不能使用索引(下标)查找元素。只能从头遍历。
  • 链表有单链表、循环单链表、双链表、循环双链表。本文以单链表举例。

添加节点:(注意指向顺序,避免数据丢失)

  • 在链表头部添加:先新节点指向第一个节点,再头指针指向新节点。
  • 在链表尾部添加:最后一个节点指向新节点。
  • 在链表指定位置添加:找到指定位置,先新节点指向下一个节点,再上一个节点指向新节点。

 删除节点:

  • 删除链表头部节点:头指针指向第二个节点。
  • 删除链表尾部节点:倒数第二个节点指向NULL。
  • 删除链表指定位置节点:找到指定位置,上一个节点指向该节点的下一个节点。


 C语言代码:

创建节点(结构体数据类型),并创建具体节点实例的函数:

// 节点(结构体数据类型)
typedef struct Node
{
    int data;                 // 数据为整数
    struct Node *next;        // 指针指向下一个节点
} LinkNode;                   // 别名LinkNode
// 创建具体节点实例的函数
LinkNode * createNode(int data)
{
	LinkNode *node = (LinkNode *)malloc(sizeof(LinkNode));   // 给节点分配内存空间
	if(node == NULL)
	{
		perror("Memory allocation failed");
		exit(-1);
	}
	node->data = data;
	node->next = NULL;
	return node;
}

本文将头指针和链表长度作为全局变量:

LinkNode *header = NULL;		// 头指针,初始化指向NULL
int length = 0;				    // 统计链表元素个数

添加节点:

// 添加节点(链表头部添加)
void addtop(int data)
{
	LinkNode *node = createNode(data);       // 调用createNode函数,创建具体节点
	node->next = header;                     // 先新节点指向头指针指向的节点
	header = node;                           // 再头指针指向新节点
	length++;                                // 每添加一个数据,length+1
}
// 添加节点(链表尾部添加)
void append(int data)
{
	if(length == 0)        // 若空链表,在链表头部添加
	{
		addtop(data);
		return ;
	}

	LinkNode *node = createNode(data);

	LinkNode *cur = header;         // 从头遍历元素,找到最后
	while(cur->next != NULL)
	{
		cur = cur->next;
	}
	cur->next = node;
	length++;
}
// 添加节点(在指定位置,位置从0开始)
void insert(int location, int data)
{
	if(length == 0)    // 若空链表,在链表头部添加
	{
		addtop(data);
		return ;
	}
	if(length <= location)    // 若链表长度<=指定位置,在链表尾部添加
	{
		append(data);
		return ;
	}

	LinkNode *node = createNode(data);

	LinkNode *prev, *cur = header;      // 使用两个指针,遍历链表,找到指定位置
	while(location > 0)
	{	
		prev = cur;
		cur = cur->next;
		location--;
	}
	
	node->next = cur;
	prev->next = node;
	length++;
}

删除节点:

// 删除节点(删除链表头部节点)
void deltop(void)
{
	if(length == 0) return ;   // 空链表,直接退出程序

	header = header->next;
	length--;                  // 每删除一个元素,length-1
}
// 删除节点(删除链表尾部节点)
void pop(void)
{	
	if(length == 0) return ;       // 空链表,直接退出程序
	if(length == 1)                // 一个元素,头指针直接指向NULL
	{
		header = NULL;
		return ;
	}

	LinkNode *prev, *cur = header;     // 使用两个指针,遍历链表,直到最后的位置
	while(cur->next != NULL)
	{
		prev = cur;
		cur = cur->next;
	}
	prev->next = NULL;
	length--;
}
// 删除节点(删除链表指定位置的节点,位置从0开始)
void delat(int location)
{
	if(length == 0) return ;          // 空链表,直接退出程序
	if(length - 1 <= location)        // 链表长度-1<=指定位置,删除链表尾部节点
	{
		pop();
		return ;
	}

	LinkNode *prev, *cur = header;     // 使用两个指针,遍历链表,直到指定位置
	while(location > 0)
	{
		prev = cur;
		cur = cur->next;
		location--;
	}
	prev->next = cur->next;
	length--;
}
// 删除节点(删除指定数据)
void del(int data)
{
	LinkNode *prev, *cur = header;      // 使用两个指针,遍历链表,比对数据内容
	while(cur != NULL)
	{
		if(cur->data == data)
		{
			if(header == cur)       // 若是第一个节点,头指针直接跳过该节点指向下一个节点
			{
				header = cur->next;
			}
			else                    // 否则 该节点上一个节点,直接跳过该节点指向下一个节点
			{
				prev->next = cur->next;
			}

			length--;
			return ;
		}
		prev = cur;
		cur = cur->next;
	}
	return ;
}

遍历节点:

void travel(void)
{
	if(length == 0) return ;       // 空链表,直接退出程序

	printf("linklist elements: ");
	LinkNode *cur = header;
	while(cur != NULL)
	{
		printf("%d \t", cur->data);
		cur = cur->next;
	}
	printf("\n");
}


完整代码:(linklist.c)

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

/* structure */
typedef struct Node			   // node structure
{
	int data;
	struct Node *next;
} LinkNode;

/* global variables */
LinkNode *header = NULL;		// header pointer
int length = 0;				    // the number of linklist elements

/* function prototype */
void addtop(int data);			// add element to the top of the linklist
void append(int data);			// add element to the end of the linklist
void insert(int location, int data);	// add element to the specify location (start with 0)
void travel(void);			// show element one by one
void deltop(void);			// delete element from the top of the linklist
void pop(void);			    // delete element from the end of the linklist
void delat(int location);   // delete element from the specify location (start with 0)
void del(int data);			// delete the specify data

/* main function */
int main(void)
{
	addtop(5);
	printf("length is %d \n", length);		
	travel();

	append(9);
	printf("length is %d \n", length);		
	travel();

	insert(1,8);
	printf("length is %d \n", length);		
	travel();

	addtop(3);
	printf("length is %d \n", length);		
	travel();

	deltop();	
	printf("length is %d \n", length);		
	travel();

	pop();
	printf("length is %d \n", length);		
	travel();

	delat(1);
	printf("length is %d \n", length);		
	travel();

	del(7);
	printf("length is %d \n", length);		
	travel();

	del(5);
	printf("length is %d \n", length);		
	travel();
}

/* subfunction */
LinkNode * createNode(int data)		// create a node
{
	LinkNode *node = (LinkNode *)malloc(sizeof(LinkNode));
	if(node == NULL)
	{
		perror("Memory allocation failed");
		exit(-1);
	}
	node->data = data;
	node->next = NULL;
	return node;
}

void addtop(int data)			// add element to the top of the linklist
{
	LinkNode *node = createNode(data);
	node->next = header;
	header = node;
	length++;
}

void append(int data)			// add element to the end of the linklist
{
	if(length == 0)
	{
		addtop(data);
		return ;
	}

	LinkNode *node = createNode(data);

	LinkNode *cur = header;
	while(cur->next != NULL)
	{
		cur = cur->next;
	}
	cur->next = node;
	length++;
}	

void insert(int location, int data)	  // add element to the specify location (start with 0)
{
	if(length == 0)
	{
		addtop(data);
		return ;
	}
	if(length <= location)
	{
		append(data);
		return ;
	}

	LinkNode *node = createNode(data);

	LinkNode *prev, *cur = header;
	while(location > 0)
	{	
		prev = cur;
		cur = cur->next;
		location--;
	}
	
	node->next = cur;
	prev->next = node;
	length++;
}

void travel(void)			// show element one by one
{
	if(length == 0) return ;

	printf("linklist elements: ");
	LinkNode *cur = header;
	while(cur != NULL)
	{
		printf("%d \t", cur->data);
		cur = cur->next;
	}
	printf("\n");
}

void deltop(void)				// delete element from the top of the linklist
{
	if(length == 0) return ;

	header = header->next;
	length--;
}

void pop(void)			// delete element from the end of the linklist
{	
	if(length == 0) return ;
	if(length == 1)
	{
		header = NULL;
		return ;
	}

	LinkNode *prev, *cur = header;
	while(cur->next != NULL)
	{
		prev = cur;
		cur = cur->next;
	}
	prev->next = NULL;
	length--;
}

void delat(int location)		// delete element from the specify location (start with 0)
{
	if(length == 0) return ;
	if(length - 1 <= location)
	{
		pop();
		return ;
	}

	LinkNode *prev, *cur = header;
	while(location > 0)
	{
		prev = cur;
		cur = cur->next;
		location--;
	}
	prev->next = cur->next;
	length--;
}

void del(int data)			// delete the specify data
{
	LinkNode *prev, *cur = header;
	while(cur != NULL)
	{
		if(cur->data == data)
		{
			if(header == cur)
			{
				header = cur->next;
			}
			else
			{
				prev->next = cur->next;
			}

			length--;
			return ;
		}
		prev = cur;
		cur = cur->next;
	}
	return ;
}

编译链接: gcc -o linklist linklist.c

执行可执行文件: ./linklist

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/755617.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Vue】Vue3基础

VUE3基础 1、简介2、创建工程2.1 基于vue-cli创建&#xff08;脚手架webpack&#xff09;2.2 基于vite创建&#xff08;推荐&#xff09;2.3 目录结构2.4 vscode插件推荐 3、核心语法3.1 选项式&#xff08;options API&#xff09;和组合式&#xff08;composition API&#x…

of_match_device是怎么匹配的

这里以spi-gpio.c为例 先判断有没有匹配表和dev中有没设备树节点 struct device中有个保存设备树节点的结构体 可通过三种方式匹配&#xff1a;名字、类型、compatible 匹配成功&#xff0c;则执行第一个

海外媒体发稿:媒体宣发套餐的作用分享-华媒舍

一、神奇媒体宣发套餐 神奇媒体宣发套餐是一项专业的多媒体宣传推广服务&#xff0c;旨在帮助企业、个人快速提升品牌知名度和曝光度。它通过全面覆盖主流媒体、社交网络以及各大网络平台&#xff0c;将您的宣传信息传递给广泛的受众群体&#xff0c;实现全方位、多角度的宣传…

无人机无刷电机理论教学培训课程

本文档为一份关于Brushless电机理论的详细教程&#xff0c;由TYTO Robotics编制&#xff0c;旨在帮助用户理解brushless电机的工作原理、特性以及如何通过实验测定其关键参数Kv和Kt。文档首先介绍了brushless电机的基本组成&#xff0c;包括静止的定子和旋转的转子&#xff0c;…

python循环结构

1.while 循环 语句&#xff1a; while 循环条件表达式&#xff1a; 代码块 else&#xff1a; 代码块 小练&#xff1a; 设计一百以内的偶数相加 n 0 while n < 100:n 1if n % 2 0 :print(n) 判断是不是闰年&#xff08;四年一润和百年不润&#xff0c;或者四百年一润&am…

Linux平台下RTSP|RTMP播放器如何跟python交互投递RGB数据供视觉算法分析

技术背景 我们在对接Linux平台RTSP播放模块的时候&#xff0c;遇到这样的技术需求&#xff0c;开发者需要把Linux RTSP播放器拉取的数据&#xff0c;除了实时播放外&#xff0c;还要投递给python&#xff0c;用于视觉算法分析。 技术实现 Linux平台RTSP、RTMP直接播放不再赘…

GoLang语言

基础 安装Go扩展 go build 在项目目录下执行go build go run 像执行脚本文件一样执行Go代码 go install go install分为两步&#xff1a; 1、 先编译得到一个可执行文件 2、将可执行文件拷贝到GOPATH/bin Go 命令 go build :编译Go程序 go build -o "xx.exe"…

React+TS前台项目实战(二十一)-- Search业务组件封装实现全局搜索

文章目录 前言一、Search组件封装1. 效果展示2. 功能分析3. 代码详细注释4. 使用方式 二、搜索结果展示组件封装1. 功能分析2. 代码详细注释 三、引用到文件&#xff0c;自行取用总结 前言 今天&#xff0c;我们来封装一个业务灵巧的组件&#xff0c;它集成了全局搜索和展示搜…

基于Java的茶文化交流系统【附源码+LW】

摘 要 计算机网络发展到现在已经好几十年了&#xff0c;在理论上面已经有了很丰富的基础&#xff0c;并且在现实生活中也到处都在使用&#xff0c;可以说&#xff0c;经过几十年的发展&#xff0c;互联网技术已经把地域信息的隔阂给消除了&#xff0c;让整个世界都可以即时通话…

Meta发布LLM编译器 称将改变我们的编程方式

Meta发布了Meta 大型语言模型&#xff08;LLM&#xff09;编译器&#xff0c;这是一套强大的开源模型&#xff0c;旨在优化代码并彻底改变编译器设计。这项创新有望改变开发人员优化代码的方式&#xff0c;使代码优化更快、更高效、更具成本效益。 在将大型语言模型应用于代码和…

基于SpringBoot+Vue的大药房管理系统(带1w+文档)

基于SpringBootVue的大药房管理系统(带1w文档) 本系统主要包括管理员和用户两个用户角色&#xff1b;主要包括&#xff1a;首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;保健品分类管理&#xff0c;药品分类管理&#xff0c;药品信息管理&#xff0c;疫情常识管理…

鸿蒙登录页面及页面跳转的设计

目录 任务目标任务分析任务实施1.新建工程项目HMLogin2.设计登录页面Index.visual3.设计第二个页面SecondPage4.修改Index.ets代码5.修改SecondPage.ets代码6.运行工程 任务目标 设计一个简单的登录页面&#xff0c;要求可以将第一页的登录信息&#xff0c;传递到第二个页面&a…

3.js - 反射率(reflectivity) 、折射率(ior)

没啥太大的感觉 反射率 reflectivity 概念 反射率&#xff1a;指的是&#xff0c;材质表面反射光线的能力反射率&#xff0c;用于控制材质对环境光&#xff0c;或光源的反射程度反射率越高&#xff0c;材质表面反射的光线越多&#xff0c;看起来就越光亮使用 适用于&#xff0…

AIGC实战:LLaMA2打造中文写作利器——数据准备与模型训练全攻略

目录 一、下载并加载中文数据集二、中文数据集处理 1、数据格式 2、数据集处理之tokenizer训练格式 1&#xff09;先将一篇篇文本拼凑到一起&#xff08;只是简单的拼凑一起&#xff0c;用于训练tokenizer&#xff09; 2&#xff09;将数据集进行合并 3、数据集处理之模型&am…

嵌入式学习——硬件(ARM体系架构)——day51

1. S3C2440基础知识——一条指令四个字节 1.1 定义 S3C2440 是三星&#xff08;Samsung&#xff09;公司设计的一款基于 ARM920T 核心的微处理器&#xff0c;广泛应用于嵌入式系统中&#xff0c;属于三星的 S3C24xx 系列。 1.2 处理器核心 ARM920T&#xff1a;基于 ARM v5T …

Shell 脚本编程保姆级教程(下)

七、Shell 流程控制 7.1 if #!/bin/bash num1100 if test $[num1] 100 thenecho num1 是 100 fi 7.2 if else #!/bin/bash num1100 num2100 if test $[num1] -eq $[num2] thenecho 两个数相等&#xff01; elseecho 两个数不相等&#xff01; fi 7.3 if else-if else #!/…

Java框架的原理主要基于以下几个核心

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…

算法力扣刷题记录 二十三【151.翻转字符串里的单词】

前言 字符串篇&#xff0c;继续。 记录 二十三【151.翻转字符串里的单词】 – 一、题目阅读 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词…

Type-C接口OTG转接器的应用与发展

随着科技的飞速发展&#xff0c;智能移动设备已成为我们生活中不可或缺的一部分。而在这些设备的连接与数据传输中&#xff0c;Type-C接口以其高效、便捷的特性逐渐占据了主导地位。OTG&#xff08;On-The-Go&#xff09;技术则进一步扩展了Type-C接口的功能&#xff0c;使得设…

融资担保行业数字化转型探索与实践

融资担保行业数字化转型探索与实践 随着全球经济的快速发展和科技的不断进步&#xff0c;数字化转型已成为各行各业提升竞争力和实现可持续发展的必然选择。融资担保行业作为金融体系中的重要组成部分&#xff0c;也在积极探索和实践数字化转型&#xff0c;以更好地服务中小微企…