C语言单向循环链表的增删操作

这篇具有很好参考价值的文章主要介绍了C语言单向循环链表的增删操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

/********************************************************************************************************
*
*
* 设计单向循环链表的接口
*
* 
*
* Copyright (c)  2023-2024   a1583839363@163.com   All right Reserved
* ******************************************************************************************************/


//指的是单向循环链表中的结点有效数据类型,用户可以根据需要进行修改
typedef int  DataType_t;

//构造单向循环链表的结点,链表中所有结点的数据类型应该是相同的
typedef struct CircularLinkedList
{
	DataType_t  		 data; //结点的数据域
	struct LinkedList	*next; //结点的指针域

}CircLList_t;


//创建一个空单向循环链表,空链表应该有一个头结点,对链表进行初始化
CircLList_t * CircLList_Create(void)
{
	//1.创建一个头结点并对头结点申请内存
	CircLList_t *Head = (CircLList_t *)calloc(1,sizeof(CircLList_t));
	if (NULL == Head)
	{
		perror("Calloc memory for Head is Failed");
		exit(-1);
	}

	//2.对头结点进行初始化,头结点是不存储数据域,指针域指向自身,体现“循环”思想
	Head->next = Head;

	//3.把头结点的地址返回即可
	return Head;
}

//创建新的结点,并对新结点进行初始化(数据域 + 指针域)
CircLList_t * CircLList_NewNode(DataType_t data)
{
	//1.创建一个新结点并对新结点申请内存
	CircLList_t *New = (CircLList_t *)calloc(1,sizeof(CircLList_t));
	if (NULL == New)
	{
		perror("Calloc memory for NewNode is Failed");
		return NULL;
	}

	//2.对新结点的数据域和指针域进行初始化
	New->data = data;
	New->next = NULL;

	return New;
}

//头插
bool CircLList_HeadInsert(CircLList_t *Head,DataType_t data)
{
	// 1.创建新的结点,并对新结点进行初始化
	CircLList_t *New = CircLList_NewNode(data);
	if (NULL == New)
	{
		printf("can not insert new node\n");
		return false;
	}

	// 2.判断单向循环链表是否为空,如果为空,则直接插入即可
	if (Head == Head->next)
	{
		Head->next = New;
        New->next = New;
		return true;
	}

    // 3.如果单向循环链表为非空,遍历找到尾结点
    CircLList_t *Last = Head;
    while(Last->next != Head->next)
    {
        Last = Last->next;
    }

	// 4.把新结点插入到链表的头部
	Last->next = New;
    New->next = Head->next;
    Head->next = New;

    return true;
}

//尾插
bool CircLList_TailInsert(CircLList_t *Head,DataType_t data)
{
	// 1.创建新的结点,并对新结点进行初始化
	CircLList_t *New = CircLList_NewNode(data);
	if (NULL == New)
	{
		printf("can not insert new node\n");
		return false;
	}

	// 2.判断单向循环链表是否为空,如果为空,则直接插入即可
	if (Head == Head->next)
	{
		Head->next = New;
        New->next = New;
		return true;
	}

    // 3.如果单向循环链表为非空,遍历找到尾结点
    CircLList_t *Last = Head;
    while(Last->next != Head->next)
    {
        Last = Last->next;
    }

    // 4.把新结点插入到链表的尾部
    Last->next = New;
    New->next = Head->next;

    return true;
}


//指定位置插入
bool CircLList_DestInsert(CircLList_t *Head,DataType_t destval,DataType_t data)
{
	// 1.创建新的结点,并对新结点进行初始化
	CircLList_t *New = CircLList_NewNode(data);
	if (NULL == New)
	{
		printf("can not insert new node\n");
		return false;
	}

	// 2.判断单向循环链表是否为空,如果为空,则直接插入即可
	if (Head == Head->next)
	{
		Head->next = New;
        New->next = New;
		return true;
	}

    // 3.遍历链表,比较结点的数据域,找到目标结点
	CircLList_t *Dest = Head->next;
	while (Dest->data != destval && Dest != NULL)
	{
		Dest = Dest->next;
	}
	if (NULL == Dest)
	{
		return false;
	}

	// 4.说明找到目标结点,则把新结点插入到目标结点的后面
	New->next = Dest->next;
	Dest->next = New;

    return true;
}

// 头删
bool CircLList_HeadDel(CircLList_t *Head)
{
	// 1.判断链表是否为空,如果为空,则直接退出
	if (Head == Head->next)
	{
		return false;
	}

    // 2.对链表的首结点的地址进行备份
	CircLList_t *Temp = Head->next;

	// 3.链表是非空的,判断是否只有首结点
	if(Head->next == Head->next->next)
	{
		Temp->next = NULL;
		Head->next = Head;
		free(Temp);
		return true;
	}

	// 4.遍历链表,找到尾结点
    CircLList_t *Last = Head;
    while(Last->next != Head->next)
    {
        Last = Last->next;
    }

    // 5.删除首结点
	Last->next = Temp->next;
    Head->next = Temp->next;
	Temp->next = NULL;
	free(Temp);

	return true;
}

// 尾删
bool CircLList_TailDel(CircLList_t *Head)
{
    // 1.判断链表是否为空,如果为空,则直接退出
	if (Head == Head->next)
	{
		return false;
	}

    // 2.链表是非空的,遍历链表,找到尾结点以及尾结点的直接前驱
    CircLList_t *Last_pre = Head;
    CircLList_t *Last = Head->next;
    while(Last->next != Head->next)
    {
        Last = Last->next;
        Last_pre = Last_pre->next;
    }

    // 3.删除尾结点
    Last_pre->next = Head->next;
    Last->next = NULL;
    free(Last);

	return true;
}

// 指定删
bool CircLList_DestDel(CircLList_t *Head, DataType_t destval, DataType_t data)
{
    // 1.判断链表是否为空,如果为空,则直接退出
	if (Head == Head->next)
	{
		return false;
	}

    // 2.链表是非空的,遍历链表,找到待删除结点以及待删除结点的直接前驱
	CircLList_t *Dest_pre = Head;
    CircLList_t *Dest = Head->next;
    while (Dest->data != destval && Dest != NULL)
	{
		Dest = Dest->next;
        Dest_pre = Dest_pre->next;
	}
	if (NULL == Dest)
	{
		return false;
	}

    // 3.删除指定结点
	Dest_pre->next = Dest->next;
    Dest->next = NULL;
	free(Dest);

	return true;
}

//遍历链表
bool CircLList_Print(CircLList_t *Head)
{
	//对单向循环链表的头结点的地址进行备份
	CircLList_t *Phead = Head;
	
	//判断当前链表是否为空,为空则直接退出
	if (Head->next == Head)
	{
		printf("current linkeflist is empty!\n");
		return false;
	}

	//从首结点开始遍历
	while(Phead->next)
	{
		//把头结点的直接后继作为新的头结点
		Phead = Phead->next;

		//输出头结点的直接后继的数据域
		printf("data = %d\n",Phead->data);

		//判断是否到达尾结点,尾结点的next指针是指向首结点的地址
		if (Phead->next == Head->next)
		{
			break;
		}	
	}

	return true;
}

int main(int argc, char const *argv[])
{
	
	return 0;
}

文章来源地址https://www.toymoban.com/news/detail-856750.html

到了这里,关于C语言单向循环链表的增删操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 单向循环链表的接口程序

    2024年04月24日
    浏览(26)
  • C语言双向链表的增删操作

    2024年04月24日
    浏览(33)
  • 【数据结构】链表:带头双向循环链表的增删查改

    本篇要分享的内容是带头双向链表,以下为本片目录 目录 一、链表的所有结构 二、带头双向链表 2.1尾部插入 2.2哨兵位的初始化 2.3头部插入 2.4 打印链表 2.5尾部删除 2.6头部删除  2.7查找结点 2.8任意位置插入 2.9任意位置删除  在刚开始接触链表的时候,我们所学仅仅所学的

    2024年02月05日
    浏览(80)
  • 【数据结构】单向链表的增删查改以及指定pos位置的插入删除

    目录  单向链表的概念及结构  尾插 头插 尾删 ​编辑  头删  查找  在pos位置前插  在pos位置后插  删除pos位置  删除pos的后一个位置 总结 代码  概念:链表是一种 物理存储结构上非连续 、非顺序的存储结构,数据元素的 逻辑顺序 是通过链表中的 指针链接 次序实现的

    2024年02月05日
    浏览(33)
  • 指针穿梭,数据流转:探秘C语言实现单向不带头不循环链表

    本篇博客会讲解链表的最简单的一种结构:单向+不带头+不循环链表,并使用C语言实现。 链表是一种线性的数据结构,而本篇博客讲解的是链表中最简单的一种结构,它的一个结点的声明如下: 一个Node中包含2个部分:data用来存储数据,被称作“数据域”;next用来存储一个

    2024年02月05日
    浏览(38)
  • 【数据结构初阶】三、 线性表里的链表(无头+单向+非循环链表 -- C语言实现)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表)-CSDN博客  =========================

    2024年02月08日
    浏览(44)
  • 单向带头链表的添加修改删除操作

      双向链表的添加操作

    2024年02月02日
    浏览(31)
  • 数据结构入门(C语言版)线性表中链表介绍及无头单向非循环链表接口实现

    概念 : 线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素 。因此,为了表示每个数据元素与其直接后继数据元素之间的逻辑关系,对数据元素来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。这

    2023年04月09日
    浏览(38)
  • C语言—实现循序表的增删查改

    嗨嗨嗨!大家好!今天我为大家分享的是数据结构知识——顺序表。废话不多数,让我们开始今天的知识分享吧。 数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。数据结构反映数据的内部构成,即数据由那部分构

    2024年04月15日
    浏览(47)
  • 【数据结构 -- C语言】 双向带头循环链表的实现

    目录 1、双向带头循环链表的介绍 2、双向带头循环链表的接口 3、接口实现 3.1 开辟结点 3.2 创建返回链表的头结点 3.3 判断链表是否为空 3.4 打印 3.5 双向链表查找 3.6 双向链表在pos的前面进行插入 3.6.1 头插 3.6.2 尾插 3.6.3 更新头插、尾插写法 3.7 双向链表删除pos位置的节点

    2024年02月09日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包