数据结构链表,结点的结构体定义以及增删改查的实现

news2024/12/26 11:30:04

一、单链表的定义和表示

线性表链式存储结构的特点是:用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。因此,为了表示每个元素a_i与其直接后继数据元素a_ i + _1之间的逻辑关系,对数据元素a_i来说,除了存储其本身的信息之外,还需要存储一个指示其直接后继的信息。这两部分信息组成数据元素a_i的存储映像,称为结点。它包括两个域:

数据域:存储数据元素信息的域

指针域:存储直接后继存储位置的域

n个结点链结成一个链表,即为线性表的链式存储结构,而每个结点只包含一个指针域称为线性链表单链表。

根据链表结点所含指针个数、指针指向和指针连接方式,可将链表分为单链表、循环链表、双向链表、二叉链表、十字链表、临近链表、临接多重表等。

首元结点:链表中存储第一个数据元素的结点

头结点:在首元结点之前附设的一个结点,其指针域指向首元结点。头节点的数据域一般存放链表的长度

头指针:指向链表中第一个结点的指针 

注意:链表的最后一个结点的指针域为NULL

二、单链表的存储结构

typedef int ElemType;  //重定义数据域的数据类型
typedef struct LNode   //定义单链表存储结构
{
	ElemType data;     //结点的数据域
	struct LNode *next;//结点的指针域
}*LinkList;            //LinkList为指向结构体LNode的指针类型

三、单链表的操作

3.1 单链表创建

LinkList Request_space()  //在堆区申请一个结点空间
{
	LinkList node=(LinkList)malloc(sizeof(struct LNode));  //在使用malloc函数时,记得引用头文件#include <stdlib.h>
	if(NULL==node)
		return NULL;
	node->data=0;
	node->next=NULL;
	return node;
}

3.2 单链表头插

LinkList insert_head(LinkList L_list,ElemType value)  //实现头插
{
	LinkList node=Request_space();
	if(NULL==node)
		return NULL;
	node->data=value;
	node->next=L_list;
	L_list=node;
	return L_list;
}

3.3 单链表尾插

LinkList insert_rear(LinkList L_list,ElemType value)  //实现尾插
{
	LinkList node=Request_space();
	node->data=value;
	if(NULL==L_list)
		L_list=node;
	else
	{
		LinkList rear=L_list;
		while(rear->next!=NULL)
			rear=rear->next;
		rear->next=node;
	}
	return L_list;
}

3.4 单链表头删

LinkList delete_head(LinkList L_list)  //实现头删
{
	if(NULL==L_list)
		return NULL;
	if(L_list->next==NULL)
	{
		free(L_list);
		L_list=NULL;
	}
	else
	{
		LinkList p=L_list->next;
		L_list->data=p->data;
		L_list->next=p->next;
		free(p);
		p=NULL;
	}
	return L_list;
}

3.5 单链表尾删

LinkList delete_rear(LinkList L_list)  //实现尾删
{
	if(NULL==L_list)
		return NULL;
	if(L_list->next==NULL)
	{
		free(L_list);
		L_list=NULL;
	}
	else
	{
		LinkList rear=L_list;
		while(rear->next->next!=NULL)
			rear=rear->next;
		free(rear->next);
		rear->next=NULL;
	}
	return L_list;
}

3.6 单链表遍历

int Output(LinkList L_list)  //实现输出
{
	if(NULL==L_list)
		return -1;
	while(L_list!=NULL)
	{
		printf("%d ",L_list->data);
		L_list=L_list->next;
	}
	puts("");
	return 0;
}

3.7 计算单链表长度

int len_Llist(LinkList L_list)  //计算单链表长度
{
	int count=0;
	if(NULL==L_list)
		return -1;
	while(L_list!=NULL)
	{
		count++;
		L_list=L_list->next;
	}
	return count;
}

3.8 单链表任意位置插入

LinkList insert_by_seat(LinkList L_list,int seat,ElemType value)  //实现任意位置插入
{
	int len=len_Llist(L_list);
	if(NULL==L_list||seat<1||seat>len+1)
		return L_list;
	if(seat==len+1)
		L_list=insert_rear(L_list,value);

	LinkList rear=L_list;
	LinkList node=Request_space();
	for(int i=1;i<seat;i++)
		rear=rear->next;
	node->data=rear->data;
	rear->data=value;
	node->next=rear->next;
	rear->next=node;
	return L_list;
}

3.9 单链表任意位置查找

int search_by_seat(LinkList L_list,int seat)  //实现任意位置查找
{
	int len=len_Llist(L_list);
	if(NULL==L_list||seat<1||seat>len+1)
		return -1;
	LinkList rear=L_list;
	for(int i=1;i<seat;i++)
		rear=rear->next;
	printf("%d\n",rear->data);
	return 0;
}

3.10 单链表任意位置修改

LinkList modify_by_seat(LinkList L_list,int seat,ElemType value)  //任意位置修改
{
	int len=len_Llist(L_list);
	if(NULL==L_list||seat<1||seat>len+1)
		return L_list;
	LinkList rear=L_list;
	for(int i=1;i<seat;i++)
		rear=rear->next;
	rear->data=value;
	return L_list;
}

3.11 单链表任意位置删除 

LinkList delete_by_seat(LinkList L_list,int seat)  //任意位置删除
{
	int len=len_Llist(L_list);
	if(NULL==L_list||seat<1||seat>len+1)
		return L_list;
	if(seat==1)
		L_list=delete_head(L_list);
	else
	{
	LinkList rear=L_list;
	for(int i=1;i<seat-1;i++)
		rear=rear->next;
	LinkList p=rear->next;
	rear->next=p->next;
	free(p);
	p=NULL;
	}
	return L_list;
}

四、多文件编辑实现单链表操作

头文件 head.h

#ifndef __HEAD_H__
#define __HEAD_H__

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

typedef int ElemType;  //重定义数据域的数据类型
typedef struct LNode  //定义单链表存储结构
{
	ElemType data;
	struct LNode *next;
}*LinkList;

LinkList Request_space();  //在堆区申请一个结点空间
int Output(LinkList L_list);  //实现输出
LinkList insert_head(LinkList L_list,ElemType value);  //实现头插
LinkList insert_rear(LinkList L_list,ElemType value);  //实现尾插
LinkList delete_head(LinkList L_list);  //实现头删
LinkList delete_rear(LinkList L_list);  //实现尾删
LinkList insert_by_seat(LinkList L_list,int seat,ElemType value);  //实现任意位置插入
int search_by_seat(LinkList L_list,int seat);  //实现任意位置查找
LinkList modify_by_seat(LinkList L_list,int seat,ElemType value);  //任意位置修改
LinkList delete_by_seat(LinkList L_list,int seat);  //任意位置删除

#endif

自定义函数 fun.c

#include "head.h"
LinkList Request_space()  //在堆区申请一个结点空间
{
	LinkList node=(LinkList)malloc(sizeof(struct LNode));
	if(NULL==node)
		return NULL;
	node->data=0;
	node->next=NULL;
	return node;
}
int Output(LinkList L_list)  //实现输出
{
	if(NULL==L_list)
		return -1;
	while(L_list!=NULL)
	{
		printf("%d ",L_list->data);
		L_list=L_list->next;
	}
	puts("");
	return 0;
}
LinkList insert_head(LinkList L_list,ElemType value)  //实现头插
{
	LinkList node=Request_space();
	if(NULL==node)
		return NULL;
	node->data=value;
	node->next=L_list;
	L_list=node;
	return L_list;
}
LinkList insert_rear(LinkList L_list,ElemType value)  //实现尾插
{
	LinkList node=Request_space();
	node->data=value;
	if(NULL==L_list)
		L_list=node;
	else
	{
		LinkList rear=L_list;
		while(rear->next!=NULL)
			rear=rear->next;
		rear->next=node;
	}
	return L_list;
}
LinkList delete_head(LinkList L_list)  //实现头删
{
	if(NULL==L_list)
		return NULL;
	if(L_list->next==NULL)
	{
		free(L_list);
		L_list=NULL;
	}
	else
	{
		LinkList p=L_list->next;
		L_list->data=p->data;
		L_list->next=p->next;
		free(p);
		p=NULL;
	}
	return L_list;
}
LinkList delete_rear(LinkList L_list)  //实现尾删
{
	if(NULL==L_list)
		return NULL;
	if(L_list->next==NULL)
	{
		free(L_list);
		L_list=NULL;
	}
	else
	{
		LinkList rear=L_list;
		while(rear->next->next!=NULL)
			rear=rear->next;
		free(rear->next);
		rear->next=NULL;
	}
	return L_list;
}
int len_Llist(LinkList L_list)  //计算单链表长度
{
	int count=0;
	if(NULL==L_list)
		return -1;
	while(L_list!=NULL)
	{
		count++;
		L_list=L_list->next;
	}
	return count;
}
LinkList insert_by_seat(LinkList L_list,int seat,ElemType value)  //实现任意位置插入
{
	int len=len_Llist(L_list);
	if(NULL==L_list||seat<1||seat>len+1)
		return L_list;
	if(seat==len+1)
		L_list=insert_rear(L_list,value);

	LinkList rear=L_list;
	LinkList node=Request_space();
	for(int i=1;i<seat;i++)
		rear=rear->next;
	node->data=rear->data;
	rear->data=value;
	node->next=rear->next;
	rear->next=node;
	return L_list;
}
LinkList delete_by_seat(LinkList L_list,int seat)  //任意位置删除
{
	int len=len_Llist(L_list);
	if(NULL==L_list||seat<1||seat>len+1)
		return L_list;
	if(seat==1)
		L_list=delete_head(L_list);
	else
	{
	LinkList rear=L_list;
	for(int i=1;i<seat-1;i++)
		rear=rear->next;
	LinkList p=rear->next;
	rear->next=p->next;
	free(p);
	p=NULL;
	}
	return L_list;
}
int search_by_seat(LinkList L_list,int seat)  //实现任意位置查找
{
	int len=len_Llist(L_list);
	if(NULL==L_list||seat<1||seat>len+1)
		return -1;
	LinkList rear=L_list;
	for(int i=1;i<seat;i++)
		rear=rear->next;
	printf("%d\n",rear->data);
	return 0;
}
LinkList modify_by_seat(LinkList L_list,int seat,ElemType value)  //任意位置修改
{
	int len=len_Llist(L_list);
	if(NULL==L_list||seat<1||seat>len+1)
		return L_list;
	LinkList rear=L_list;
	for(int i=1;i<seat;i++)
		rear=rear->next;
	rear->data=value;
	return L_list;
}

主函数 main.c

#include "head.h"
int main(int argc, const char *argv[])
{
	LinkList L_list=NULL;  //定义结点变量,注意定义时一定要指向NULL
	int n;            //定义循环输入次数
	ElemType value;   //定义数据域元素
	printf("please enter n:");
	scanf("%d",&n);

 	for(int i=0;i<n;i++)  //尾插
	{
		printf("please enter a value:");
		scanf("%d",&value);
		L_list=insert_head(L_list,value);
	}

	for(int i=0;i<n;i++)  //头插
	{	
		printf("please enter a value:");
		scanf("%d",&value);
		L_list=insert_rear(L_list,value);
	}
	Output(L_list);

	int seat;

	
	printf("please enter a seat:");  //任意位置插入
	scanf("%d",&seat);
	printf("please enter a value:");
	scanf("%d",&value);
	L_list=insert_by_seat(L_list,seat,value);
    Output(L_list);

	printf("please enter a seat:");  //任意位置查找
	scanf("%d",&seat);
	search_by_seat(L_list,seat);
	Output(L_list);

	printf("please enter a seat:");  //任意位置修改
	scanf("%d",&seat);
	printf("please enter a value:");
	scanf("%d",&value);
	modify_by_seat(L_list,seat,value);
    Output(L_list);

	printf("please enter a seat which you want to delete:");  //任意位置删除 
	scanf("%d",&seat);
	delete_by_seat(L_list,seat);
	Output(L_list);
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于G6的弓字形流程图

需求 现在有个需求是类似于步骤条、流程图&#xff0c;但是节点比较多。 搜了很多类似组件&#xff0c;还是有各种问题。 尝试过的已有组件 一开始用的是element-ui自带的步骤条组件&#xff08;下图所示&#xff09;&#xff0c;但是节点过多&#xff0c;宽度不够的时候&am…

提升按钮效力:七大基本原则全面解析

按钮是交互设计中的基本元素。他们在用户和系统之间扮演重要角色。在本文中&#xff0c;我们将一起思考创建有效按钮所需了解的七个基本原则。 ⬇⬇⬇点击获取更多设计资源 https://js.design/community?categorydesign&sourcecsdn&planbbqcsdn768 让按钮看起来像按…

基于RASC的keil电子时钟制作(瑞萨RA)(1)----安装RASC

基于RASC的keil电子时钟制作_瑞萨RA_1安装RASC 概述硬件准备视频教程RA Smart Configurator软件下载RASC安装Keil下Renesas RA pack包安装 概述 RA Smart Configurator"是一种基于"灵活组合软件"概念的代码生成辅助工具。它可以自动生成微控制器的初始配置程序…

开源图片AI工具:推动计算机视觉领域的创新和合作

在当今数字化时代&#xff0c;人工智能技术的快速发展带来了许多令人兴奋的创新和应用。图片AI作为其中之一&#xff0c;为我们提供了全新的视觉体验和创作可能性。随着开源技术的推动&#xff0c;越来越多的图片AI工具被引入市场&#xff0c;为个人我们和开发者们带来了更多便…

Kafka消息监控管理工具Offset Explorer的使用教程

1、kafka监控管理工具 Offset Explorer是一款用于监控和管理Apache Kafka集群中消费者组偏移量的开源工具。它提供了一个简单直观的用户界面&#xff0c;用于查看和管理Kafka消费者组偏移量的详细信息。 Offset Explorer具有以下主要功能和特点&#xff1a; 实时监控&#x…

AVLTree深度剖析(单旋)

前言 二叉树搜索树是存在一定的缺陷问题的&#xff0c;当我们要插入的数据是有序&#xff0c;或者说接近于有序&#xff0c;&#xff0c;二叉搜索树及有可能退化为单支树&#xff0c;查找元素相当于在顺序表当中搜索元素&#xff0c;效率低下 --------------------------------…

LeetCode1657. 确定两个字符串是否接近

确定两个字符串是否接近 提示 中等 55 相关企业 如果可以使用以下操作从一个字符串得到另一个字符串&#xff0c;则认为两个字符串 接近 &#xff1a; 操作 1&#xff1a;交换任意两个 现有 字符。 例如&#xff0c;abcde -> aecdb 操作 2&#xff1a;将一个 现有 字符的每…

仓库管理软件有哪些功能?2023仓库管理软件该如何选?

对于现代企业或批发零售商&#xff0c;高效的仓库管理是确保供应链运作顺畅、库存控制精准的关键要素。在数字化时代&#xff0c;越来越多的企业和商户意识到采用仓库管理软件的重要性。 无论您是中小型企业还是中小商户&#xff0c;仓库管理都是不可忽视的一环。 一、选择仓库…

微信小程序开发闭到眼睛创建分包和详细解释

一、普通分包创建 1.介绍 说明&#xff1a;微信小程序分包是指将小程序的代码和资源按照一定规则分成多个包&#xff0c;减少首次加载时间&#xff0c;提高用户体验。分包可以有效减少小程序包的总大小&#xff0c;提高启动速度&#xff0c;减少首次加载时间。分包可以根据业…

实现小程序商城首页【源码公开】

效果图 页面源码 <view class"index-container"><view class"header"><!--搜索框【仅样式&#xff0c;不做处理】 start--><van-search bindtap"clickSearch" disabled shape"round" background"#9c7bf0&q…

在idea中搭建微服务项目(22版),详细教程

1.创建新的项目 2.创建的项目类型为SpringBoot 选择创建后再选择新建项目 3. 将新建的项目中不需要的东西都给删了,只留下pom文件即可 修改pom文件的版本 <version>2.1.6.RELEASE</version> 导入所需要的jar包,将原来<dependencies>中的依赖覆盖掉 <!-- …

10 卷积网络 convolutional networks

卷积 如果将图片从 H ∗ W ∗ C H*W*C H∗W∗C 拉伸到 N ∗ 1 N*1 N∗1 的维度&#xff0c;而参数矩阵又是 N ∗ M N*M N∗M 的大小。N很大&#xff0c;M也很大。整个网络中的参数量会变得巨大。 卷积过程&#xff0c;使用一个filter 在整个图片上滑动。 当然输入的图象可…

普通人决策正确率如何提升

简洁回复&#xff1a;非常非常非常难&#xff0c;几乎不能。 举个简单例子&#xff1a; 高考报志愿&#xff0c;能走到高考这一步的并取得成绩的&#xff0c;从幼儿园到高中&#xff0c;3633&#xff0c;这个赛道奔跑了15年。 大部分人这里指的是考生自己&#xff0c;花费在填…

Unity LayerMask原理和判断包含关系

在本文之前&#xff0c;请先了解全部位操作的含义&#xff0c;否则继续下去会很困难。 本质&#xff1a;32位整数的每一位表示一个层 LayerMask本质上是一个32位的整数(Int32 ,int)&#xff0c;每个位代表一个图层&#xff0c;因此LayerMask最多可以表示32个图层&#xff08;0…

Vue3组件间的通信方式

目录 1.props父向子组件通信 2.自定义事件 子向父组件通信 3.全局事件总线 4.v-model组件通信&#xff08;父子组件数据同步&#xff09; 绑定单个数据同步 绑定多个数据同步 5.useAttrs组件通信 6.ref与$parent ref获取子组件实例对象 $parent获取父组件实例对象 7.p…

大采购,助力提升国有企业采购供应链管理水平

2023年7月11日-12日&#xff0c;由中国物流与采购联合会主办、北京筑龙承办的主题为“数智赋能创新发展”的“第四届国有企业数智化采购与智慧供应链论坛”在北京盛大举行。来自中央企业、地方国企采购与供应链部门相关负责人、业界专家、行业媒体代表等齐聚一堂、共襄盛会。北…

HCIP第十二天

题目 拓扑图 sw1、sw2、sw3分别创建VLAN、划分接口&#xff0c;配置干道 VLAN间路由 所有PC通过DHCP获取IP地址 PC1/3可以正常访问PC2/4/5/6

【学会动态规划】解码方法(4)

目录 动态规划怎么学&#xff1f; 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后&#xff1a; 动态规划怎么学&#xff1f; 学习一个算法没有捷径&#xff0c;更何况是学习动态规划&#xff0c; 跟我…

国内流行的数据可视化软件工具

在信息爆炸的时代&#xff0c;越来越多的数据堆积如山。但是&#xff0c;这些密集的数据没有重点且可读性较差。因此&#xff0c;我们需要数据可视化来帮助数据易于理解和接受。相比之下&#xff0c;可视化更直观、更有意义&#xff0c;使用适当的数据可视化工具来可视化数据非…

C++入门 - 1(几分钟让你快速入门C++)

c入门 1. C关键字(C98)2. 命名空间2.1 命名空间定义2.2 命名空间使用 3. C输入&输出4.缺省参数4.1 缺省参数概念4.2 缺省参数分类 5. 函数重载5.1 函数重载概念5.2 C支持函数重载的原理--名字修饰(name Mangling)提问&#xff1a;C语言中为什么没有函数重载呢&#xff1f; …