数据结构单向循环链表,创建以及增删改查的实现

news2024/11/24 2:18:12

一、单向循环链表的描述

循环链表:是另一种形式的链式存储结构。其特点是表中最后一个结点的指针域指向头节点,整个链表形成一个环。

单向循环链表的操作和单链表操作基本一致,差别在于:当链表遍历时,判别当前指针p是否指向表尾结点的终止条件不同。在单链表中,判别条件一般为p!=NULL或p->next!=NULL,而单向循环链表的判别条件为p!=L或p->next!=L。

二、单向循环链表存储结构

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));
	if(NULL==node)
		return NULL;
	node->data=0;
	node->next=node;
	return node;
}

3.2 循环链表遍历

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

3.3 循环链表头插

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

3.4 循环链表尾插

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!=L_list)
			rear=rear->next;
		rear->next=node;
		node->next=L_list;
	}
	return L_list;
}

3.5 循环链表头删

LinkList delete_head(LinkList L_list)  //实现头删
{
	if(NULL==L_list)
		return NULL;
	if(L_list->next==L_list)
	{
		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.6 循环链表尾删

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

3.7 循环链表解决约瑟夫环问题

int Joseph_loop(LinkList L_list,int n,int m)  //单向循环链表实现约瑟夫环
{
	LinkList p=L_list;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m-2;j++)
		{
			p=p->next;
		}
		LinkList q=p->next;
		p->next=q->next;
		printf("%d ",q->data);
		free(q);
		q=NULL;
		p=p->next;
	}
	return 0;
}

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

头文件 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);  //实现尾删
int Joseph_loop(LinkList L_list,int n,int m);  //单向循环链表实现约瑟夫环

#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=node;
	return node;
}
int Output(LinkList L_list)  //实现输出
{
	if(NULL==L_list)
		return -1;
	LinkList p=L_list;
	do
	{
		printf("%d ",p->data);
		p=p->next;
	}while(p!=L_list);
	puts("");
	return 0;
}
LinkList insert_head(LinkList L_list,ElemType value)  //实现头插
{
	LinkList node=Request_space();
	if(NULL==node)
		return L_list;  
	if(NULL==L_list)
	{
		L_list=node;
		node->data=value;
	}
	else
	{
		node->next=L_list->next;
		L_list->next=node;
		node->data=L_list->data;
		L_list->data=value;
	}
	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!=L_list)
			rear=rear->next;
		rear->next=node;
		node->next=L_list;
	}
	return L_list;
}
LinkList delete_head(LinkList L_list)  //实现头删
{
	if(NULL==L_list)
		return NULL;
	if(L_list->next==L_list)
	{
		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==L_list)
	{
		free(L_list);
		L_list=NULL;
	}
	else
	{
		LinkList rear=L_list;
		while(rear->next->next!=L_list)
			rear=rear->next;
		free(rear->next);
		rear->next=L_list;
	}
	return L_list;
}

int Joseph_loop(LinkList L_list,int n,int m)  //单向循环链表实现约瑟夫环
{
	LinkList p=L_list;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m-2;j++)
		{
			p=p->next;
		}
		LinkList q=p->next;
		p->next=q->next;
		printf("%d ",q->data);
		free(q);
		q=NULL;
		p=p->next;
	}
	return 0;
}

主函数 main.c

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

	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);
	}
	L_list=delete_head(L_list);  //头删
	L_list=delete_rear(L_list);  //尾删
	Output(L_list);

	//约瑟夫环
	int m;
	printf("please enter the number of people:");
	scanf("%d",&n);
	printf("please enter the number you want to break:");
	scanf("%d",&m);
	for(int i=0;i<n;i++)  
	{	
		L_list=insert_rear(L_list,i+1);
	}
	Joseph_loop(L_list,n,m);

	return 0;
}

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

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

相关文章

数据分析的iloc和loc功能

大家好&#xff0c;在处理大型数据集时&#xff0c;使用有效的数据操作和提取技术是必要的。Pandas数据分析库提供了强大的工具&#xff0c;用于处理结构化数据&#xff0c;包括使用iloc和loc函数访问和修改DataFrame元素的能力。在本文中&#xff0c;我们将探讨iloc和loc之间的…

硬件设计 之 M.2接口常用知识

M.2接口 也被称为NGFF&#xff08;Next Generation Form Factor&#xff09;&#xff0c;是一种用于固态硬盘&#xff08;SSD&#xff09;和无线网络适配器等设备的高速接口标准。它是一种小型、高密度、高速度的接口&#xff0c;可用于替代传统的SATA接口和PCI Express Mini卡…

.NET网络编程——TCP通信

一、网络编程的基本概念 : 1. 网络 就是将不同区域的电脑连接到一起&#xff0c;组成局域网、城域网或广域网。把分部在不同地理区域的计算机于专门的外部设备用通信线路 互联成一个规模大、功能强的网络系统&#xff0c;从而使众多的计算机可以方便地互相传递信息&#xff0c…

gd32f103vbt6 串口OTA升级5-combin部分

一. 简介 本文主要是bin文件的组成进行一些简单介绍&#xff0c;方便理解升级的过程。 二.硬件部分 2.1 rk3399cpugd32f103 2.2 连接方式&#xff1a;串口&#xff08;115200&#xff0c;8N1&#xff09;或者iic&#xff08;本文没有介绍iic&#xff09; 三、其他需要说明的软…

销售自动化如何提高团队生产力?从这5个方面发力

任何用于减少人工劳动和缩短销售流程相关任务时间的技术&#xff0c;都可定义为销售自动化。 对于忙碌的销售人员来说&#xff0c;流程自动化是真正的救星。它可以使他们的工作简化30%&#xff0c;让他们更专注于创收任务。这将显著提高团队的工作效率&#xff0c;并带来许多其…

第二十一章:CCNet:Criss-Cross Attention for Semantic Segmentation ——用于语义分割的交叉注意力

0.摘要 全图像依赖关系为视觉理解问题提供了有用的上下文信息。在这项工作中&#xff0c;我们提出了一种称为Criss-Cross Network&#xff08;CCNet&#xff09;的方法&#xff0c;以更有效和高效的方式获取这种上下文信息。具体而言&#xff0c;对于每个像素&#xff0c;CCNet…

JVM系列(8)——对象的内存布局

1、对象的创建过程 加载-验证-准备-解析-初始化-申请内存-成员变量赋初始值-加载构造方法。 前半段是JVM系列&#xff08;5&#xff09;——类加载过程&#xff0c;申请内存可参考&#xff1a;JVM系列&#xff08;3&#xff09;——内存分配与回收策略。 2、对象在内存中的存…

python使用Anconda安装Cartopy

安装 Cartopy的话官方推荐是使用conda安装&#xff0c;打开Anconda Prompt后&#xff0c;新建一个环境&#xff08;如果已有环境可跳过这步&#xff09;&#xff0c;然后激活环境&#xff1a; conda create -n newenv python3.9 conda activate newenv接着按照官网的推荐在Anc…

JavaScript——基础知识及使用

初识 JavaScript JavaScript (简称 JS) 是世界上最流行的编程语言之一.一个脚本语言, 通过解释器运行.主要在客户端(浏览器)上运行, 现在也可以基于 node.js 在服务器端运行. JavaScript 的能做的事情: 网页开发(更复杂的特效和用户交互)网页游戏开发服务器开发(node.js)桌…

使用Jenkins自由风格的软件项目实现接口自动化测试持续集成

这里写目录标题 一、JOB项目配置1、添加描述2、限制项目的运行节点3、源码管理4、构建触发器5、构建步骤6、构建后操作 一、JOB项目配置 1、添加描述 可选选项可填可不填 2、限制项目的运行节点 节点中要有运行环境所需的配置 节点配置教程&#xff1a;https://blog.csdn…

详解c++---特殊类设计

目录标题 设计一个不能被拷贝的类设计一个只能从堆上创建对象的类设计一个只能在栈上创建对象的类设计一个无法被继承的类什么是单例模式饿汉模式饿汉模式的缺点懒汉模式懒汉模式的优点懒汉模式的缺点特殊的懒汉 设计一个不能被拷贝的类 拷贝只会放生在两个场景中&#xff1a;…

Apache Doris (三十一):Doris 数据导入(九)Spark Load 4- 导入Hive数据及注意事项

目录 1. Spark Load导入Hive非分区表数据 2. Spark Load 导入Hive分区表数据 3. 注意事项 进入正文之前&#xff0c;欢迎订阅专题、对博文点赞、评论、收藏&#xff0c;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; 宝子们订阅、点赞、收藏不迷路&#xff01;抓紧…

这8种算法

一个程序员一生中可能会邂逅各种各样的算法&#xff0c;但总有那么几种&#xff0c;是作为一个程序员一定会遇见且大概率需要掌握的算法。今天就来聊聊这些十分重要的“必抓&#xff01;”算法吧~ 算法一&#xff1a;快速排序法 快速排序法是对冒泡排序的一种改进&#xff0c…

Spring Cloud Gateway - 新一代微服务API网关

Spring Cloud Gateway - 新一代微服务API网关 文章目录 Spring Cloud Gateway - 新一代微服务API网关1.网关介绍2.Spring Cloud Gateway介绍3.Spring Cloud Gateway的特性4.Spring Cloud Gateway的三大核心概念5.Gateway工作流程6.Gateway核心配置7.动态路由8.Predicate自定义P…

vue 集成tinymce2实现图片,视频以及文件的上传

vue 集成tinymce2实现图片&#xff0c;视频以及文件的上传 1. 安装插件 &#xff08;1&#xff09;安装tinymce npm install tinymce -S &#xff08;2&#xff09;安装tinymce-vue npm install tinymce/tinymce-vue3.0.1 -S 2. 复制静态文件到public目录 资源下载路径&…

day40-Mybatis(resultMap拓展)

0目录 Mybatis-resultMap拓展 1.2.3 1.数据库字段和javabean实体类属性不一致时 解决方案1&#xff1a;将sql语句中给予别名&#xff08;别名同javabean中实体类保持一致&#xff09; 解决方案2&#xff1a;使用resultMap 2.两表关联&#xff08;用户表和角色表关联查询&…

QGIS绘制一张地图——建立打印布局在地图中添加图例和比例尺后,将地图保存为图片(出图)

前言 本节所述内容,基于上节所绘制的北京市区地图为例,特此说明! 北京市区地图如图所示: 一、直接保存为图片 依次点击工程、导入/导出、导出地图为图片: 设置比例尺、像素等信息,点击保存: 保存出来的地图的显示区域是和QGIS中看到的地图区域一样的: 二、建立…

qiankun:react18主应用 + 微应用 react18 + vue3

一&#xff1a;主应用 搭建react项目 npx create-react-app react-qiankun-main安装Antd npm install antd –save在 index.js中引入 import { ConfigProvider } from "antd"; import zhCN from "antd/locale/zh_CN"; import "antd/dist/reset.css…

心电前置放大电路制作与原理详细分析(附电路板实物图)

1、软件平台:Multisim仿真软件、EDA原理图绘制软件、医学电子学开发平台 2、硬件平台:心电示教仪、示波器、信号发生器、除颤仪、电烙铁 3、元件清单: 实验电路图 1、心电放大器原理图 2、50Hz双T陷波滤波器原理图 原理解释与计算 (1)一级放大电路 一级放大电路由…

【PCB专题】如何在Allegro中定义字体及批量修改丝印

在PCB板上丝印往往包含了很多信息,比如元件边界、元件参数、元件编号、极性、静电标识、板号等,这些信息在生产、测试及后期维护等都需要使用。一个好的设计往往都能从丝印的布局、丝印的完整性上体现出来。如下所示PCB在电解电容旁有极性丝印、电阻旁有电阻的位号信息等。 …