C++数据结构笔记(8)循环链表实现

2023-11-08

1.循环链表与单链表的区别在于尾部结点存在指向头结点的指针

2.无论尾部结点指向第一个结点(头结点)还是第二个结点(第一个有效结点),都可以被称为循环链表

3.判断循环结束的两种方式:遍历次数等于size;或判断next指针是否指向头结点

4.在初始化时,头结点需要指向自己


CirCleLinkLsist.h头文件

#ifndef CIRCLELINKLIST
#define CIRCLELINKLIST

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

//结点结构体 
typedef struct CirCleLinkNode{
	struct CirCleLinkNode* next;
}CirCleLinkNode;
//链表结构体 
typedef struct CirCleLinkList{
	CirCleLinkNode head;
	int size;
	//结构体的本质就是维护链表的诸多性质 
}CirCleLinkList;

//比较回调 
typedef int(*ComPareNode)(CirCleLinkNode*,CirCleLinkNode*);
//打印回调
typedef void(*PrintNode)(CirCleLinkNode*); 

//初始化
CirCleLinkList* Init_CirCleLinkList();
//插入
void Insert_CirCleLinkList(CirCleLinkList *clist,int pos,CirCleLinkNode* data);
//获取第一个元素 
CirCleLinkNode* Front_CirCleLinkList(CirCleLinkList* clist,int pos);
//根据位置删除
void RemoveByPos_CirCleLinkList(CirCleLinkList* clist,int pos);
//根据值删除 
void RemoveByValue_CirCleLinkList(CirCleLinkList* clist,CirCleLinkNode* data,ComPareNode compare);
//获得链表长度
int Size_CirCleLinkList(CirCleLinkList* clist); 
//判断是否为空
int IsEmpty_CirCleLinkList(CirCleLinkList* clist); 
//按值查找
int Find_CirCleLinkList(CirCleLinkList* clist,CirCleLinkNode* data,ComPareNode compare);
//打印
void Print_CirCleLinkList(CirCleLinkList* clist,PrintNode print);
//释放内存
void FreeSpace_CirCleLinkList(CirCleLinkList* clist);

#endif

CirCleLinkLsist.c源文件

初始化

CirCleLinkList* Init_CirCleLinkList(){
	
	CirCleLinkList* clist=(CirCleLinkList*)malloc(sizeof(CirCleLinkList)) ;
	clist->head.next=&(clist->head);
	clist->size=0;
	
	return clist;
}

插入

void Insert_CirCleLinkList(CirCleLinkList *clist,int pos,CirCleLinkNode* data){
	if(clist==NULL)
		return;
	if(data==NULL)
		return;
	if(pos<0||pos>clist->size)
		pos=clist->size;
	//如果越界则直接在最后一位插入即可 
	//创建辅助指针
	CirCleLinkNode* pCurrent=&(clist->head);
	for(int i=0;i<pos;i++)
	 	pCurrent=pCurrent->next;
	//新数据入链表
	data->next=pCurrent->next;
	pCurrent->next=data;
	
	clist->size++;
	
}

获取第一个元素 

CirCleLinkNode* Front_CirCleLinkList(CirCleLinkList* clist,int pos){
	return clist->head.next;
	//注意返回的是头结点的下一位 
}

根据位置删除

void RemoveByPos_CirCleLinkList(CirCleLinkList* clist,int pos){
	if(clist==NULL)
		return;
	if(pos<0||pos>=clist->size)
		return;
	CirCleLinkNode* pCurrent=&(clist->head);
	for(int i=0;i<pos;i++)
	 	pCurrent=pCurrent->next;
	
	//缓存目标被删除结点的下一个结点
	
	CirCleLinkNode* pNext=pCurrent->next; 
	pCurrent->next=pCurrent->next;
	
	clist->size--;
}

根据值删除 

void RemoveByValue_CirCleLinkList(CirCleLinkList* clist,CirCleLinkNode* data,ComPareNode compare){
	if(clist==NULL)
		return;
	if(data==NULL)
		return;
		
	CirCleLinkNode* pPrev=&(clist->head);
	CirCleLinkNode* pCurrent=pPrev->next;
	for(int i=0;i<=clist->size;i++)
	{
		if(compare(pCurrent,data)==1)
		{
			pPrev->next=pCurrent->next;
		}
			break;
		//指针后移 
		pPrev=pCurrent;
		pCurrent=pPrev->next;
	}
	clist->size--;
}

获得链表长度

int Size_CirCleLinkList(CirCleLinkList* clist){
	return clist->size;
}

判断是否为空

int IsEmpty_CirCleLinkList(CirCleLinkList* clist){
	if(clist->size==0)
		return 1;
	else
		return 0;
	
	return 0;
}

按值查找

int Find_CirCleLinkList(CirCleLinkList* clist,CirCleLinkNode* data,ComPareNode compare){
	if(clist==NULL)
		return -1;
	if(data==NULL)
		return -1;
	
	int flag=-1;
	CirCleLinkNode* pCurrent=clist->head.next;
	for(int i=0;i<clist->size;i++)
	{
		if(compare(pCurrent,data)==1)
		{
			flag=i;
			break;
		}
		pCurrent=pCurrent->next;
	} 
	return flag;
}

打印

void Print_CirCleLinkList(CirCleLinkList* clist,PrintNode print){
	if(clist==NULL)
		return;
	CirCleLinkNode* pCurrent=clist->head.next;
	for(int i=0;i<clist->size;i++)
	{
		if(pCurrent==&(clist->head))
			pCurrent=pCurrent->next;
			//成倍打印时要跳过头结点 
		print(pCurrent);
		pCurrent=pCurrent->next;
	}

}

释放内存

void FreeSpace_CirCleLinkList(CirCleLinkList* clist){
	if(clist==NULL)
		return;
	free(clist); 
}

main.cpp测试文件

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
#include"CircleLinkList.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

typedef struct goal{
	CirCleLinkNode node;
	int num;
	string name;
}goal; 

void MyPrint(CirCleLinkNode* data)
{
	goal* g=(goal*)data;
	cout<<(g->name)<<":"<<(g->num)<<endl;	
} 

int main(int argc, char** argv) {
	goal g1,g2;
	
	g1.name="Jsl";
	g2.name="Hyh";
	g1.num=2019;
	g2.num=2013;
	
	CirCleLinkList* clist=Init_CirCleLinkList();
	
	Insert_CirCleLinkList(clist,0,(CirCleLinkNode*)&g1);
	Insert_CirCleLinkList(clist,0,(CirCleLinkNode*)&g2);
	cout<<"一共有几个元素:"<<(Size_CirCleLinkList(clist))<<endl;
	//头部插入(合法范围内任意) 
	Print_CirCleLinkList(clist,MyPrint);
	FreeSpace_CirCleLinkList(clist);
	
	return 0;
}

测试结果如下:

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++数据结构笔记(8)循环链表实现 的相关文章

随机推荐

  • 标签传递算法:java版

    标签传递算法 java版 标签传递算法 java版 java labelpropagation 本地测试 数据集 LPAlgorithm loadJSON vertexAdjMap和vertexInAdjMap的区别在哪里 根据每个节点的权
  • 【计算机视觉

    文章目录 一 前言 二 简介 三 相关方法 3 1 实时目标检测器 3 2 端到端目标检测器 3 3 目标检测的多尺度特征 四 检测器端到端速度 4 1 分析NMS 4 2 端到端速度基准 五 The Real time DETR 5 1
  • 我的世界虚拟服务器联机,我的世界模拟城市联机教程-的世界怎么联机

    我的世界联机分为服务器联机和本地WIFI联机两种 首先我们先说下服务器联机方法 一 打开游戏后 点击Play进入游戏列表 再点击右上角的Edit 然后点击External 然后将会进入添加服务器的界面 第一行 ServerName 那里填写
  • 安卓默认启动的活动界面

    是在AndroidManifest 的activity 的标签中 加入 的活动是默认启动的
  • ENVI5.3安装

    一 下载地址 BT下载地址 链接 https pan baidu com s 1Z1l0qXQjSaEf3VQj9 qcAw 提取码 4il4 压缩包下载 链接 https pan baidu com s 1EbdO0uDiBdbFFdQx
  • java中定义score方法_elasticsearch 自定义 script score JavaAPI查询详解

    一 自定义score的应用场景 先打个比方 比如新产品上架了 我想让最新上架的产品搜索时候 排在前面 怎么办呢 很简单按时间排序 嗯这种方法很好实现 但下面又有个需求 比如我要求排序中上架时间的比重为40 自营产品为20 促销产品的比重为4
  • git branch管理常用命令

    本文转载至 http www 2cto com os 201307 229235 html git branch管理常用命令 查看本地分支 plain git branch dev master 代表当前位于dev分支 查看远程分支 pla
  • python netcdf4读取nc格式的气象数据

    一 nc格式数据介绍 NetCDF全称为network Common Data Format 中文译法为 网络通用数据格式 netcdf文件开始的目的是用于存储气象科学中的数据 现在已经成为许多数据采集软件的生成文件的格式 从数学上来说 n
  • PROJ4是什么?

    GIS Geographic Information System 地理信息系统 领域中最常提及 的一个概念是坐标系统 当我们提及一个地理位置的时候 与之伴随而产生的是该位置必定在一个空间参考下 当我们使用GPS设备获取到某个位置的经纬度的
  • Linux常用配置及硬件检测命令

    一些比较常见的linux命令 主要用于检测服务器的配置和硬件信息 包括 操作系统 CPU 内存 硬盘分区 系统时间 负载 网络相关 进程 用户 开关机 启动等方面 适用于主流操作系统 常见的centos ubuntu debian等 操作系
  • python selenium 三种等待方式详解

    引言 当你觉得你的定位没有问题 但是却直接报了元素不可见 那你就可以考虑是不是因为程序运行太快或者页面加载太慢造成了元素还没出来就已经报错了 试着程序调试程序运行速度 等待元素可见再继续运行程序 1 强制等待 sleep 优点 简单明了 需
  • 【国家参考文献标准GB/T 7714—2015】

    GB T 7714 2015 2 1 参考文献著录方法几种主要类型的参考文献 专著 专著中的析出文献 连续出版物 连续出版物中的析出文献 专利文献 电子文献等 的著录项目与格式要求如下 2 1 1 专著 图书 M 指以单行本或多卷册形式 在
  • 游戏开发unity编辑器扩展知识系列:获取选中文件的路径

    参考 Unity 编辑器下获取选择文件路径
  • Python中如何输出换行?

    Python中如何输出换行 在Python中 输出换行可以使用的方法有两种 分别是用转义符号或使用print 接下来我们通过这篇文章为大家详细的讲解一下 方法1 用转义符号 str3 老男孩教育 n str4 帮助有志向的年轻人通过努力学习
  • Threejs + vue 学习- VR 看房

    知识点 参考链接 threejs github 图片下载 https gitee com congyingcy threejs learning tree master three public imgs 直接跳转 代码下载 直接跳转 立方
  • maven自定义Archetype

    1 创建模板项目 如下 2 模板项目的pom xml中添加archetype插件
  • 光纤验收测试标准、参数及常用设备

    在光纤工程项目中必须执行一系列的测试以确保其完整性 一根光缆从出厂到工程安装完毕 需要进行机械测试 几何测试 光测及传输测试 前3个测试一般在工厂进行 传输测试则是光缆布线系统工程验收的必要步骤 综合布线工程电气测试包括电缆系统电气性能测试
  • ChatGPT追祖寻宗:GPT-1论文要点解读

    论文地址 Improving Language Understanding by Generative Pre Training 最近一直忙着打比赛 好久没更文了 这两天突然想再回顾一下GPT 1和GPT 2的论文 于是花时间又整理了一下
  • mysql(十)mysql主从复制--主库切换

    概述 可能为了更迭升级服务器 或者主库出现问题 又或者只是希望重新分配容量 此时需要切换主库 如果这是计划内的切换 会相对容易点 只需要在从库上使用CHANGE MASTER TO命令 并设置合适的值 大多数的值都是可选的 至少要指定需要改
  • C++数据结构笔记(8)循环链表实现

    1 循环链表与单链表的区别在于尾部结点存在指向头结点的指针 2 无论尾部结点指向第一个结点 头结点 还是第二个结点 第一个有效结点 都可以被称为循环链表 3 判断循环结束的两种方式 遍历次数等于size 或判断next指针是否指向头结点 4