双向循环链表

双向循环链表是一种较为特殊的链表,也是一种常见的数据结构,其头尾相连,各节点之间可互相访问,在单链表中,只能依次向后访问,无法访问上一个节点,而双链表可以依次向下访问也可向上访问。

链表形式
在这里插入图片描述
双链表有很多节点形象的依次连接在一起,每个节点都由一个数据域和两个指针域构成,尾指针存放着下一个节点的地址,头指针存放着上一个节点的地址,故而形象的使各个节点依次相连。

插入一个节点:

在这里插入图片描述
在1、3节点之间插入节点2,1节点尾指针原本指向3节点,改变其指向,使之指向2节点,2节点的头指针便指向1节点,同理,改变3节点的头指针指向,使之指向2节点,2节点的尾指针指向3节点。

删除一个节点
在这里插入图片描述
例如删除2节点,只需将原3(现2节点)节点的地址赋给1节点的尾指针中,3节点的头指针指向1,再将原2(即删除的节点)节点的指针域释放掉即可

头插

循环双链表的链表头一般没有数据,且一般保持这个位置不动,所以访问数据是从第二个节点开始,如果在链表头后一直插入数据,则第二个节点一直都是新数据,所以其实是对双链表进行的是前插操作。

尾插

如果在链表头插入新数据,那么出现在链表头前面的都是新数据,所以和插在链表尾是一个道理,因为双向循环链表是首尾相连的。

具体代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h> typedef struct ListNode
{struct ListNode  *front;int data;struct ListNode* next;
}ListNode;typedef struct List
{ListNode *head;
}List;void init(List* plist)//初始化
{//分配空间plist->head =(ListNode*)malloc(sizeof(ListNode));//让头指针和尾指针都指向自己plist->head->front= plist->head;plist->head->next= plist->head;
}int  data_num(List*  plist)//检查链表节点个数
{ListNode* tem;int  i = 0;for (tem =plist->head->next; tem != plist->head; tem = tem->next){i++;}return i;//返回链表节点个数
}void insert_front(ListNode*  plist, intdata)     //链表头前插
{//分配空间ListNode* cur =(ListNode*)malloc(sizeof(ListNode));//记录链表头尾指针的内容,存放的是一个节点的地址,即tem临时充当这个节点ListNode* tem =plist->next;cur->data = data;plist->next = cur;
//使链表头的尾指针指向新插进来的节点cur->front =plist;//新插进来的节点的头指针指向链表头tem->front =cur;  //使tem节点的头指针指向新插进来的节点cur->next =tem;   //新插进来的尾指针指向tem} void forntinsert_list(List* plist, int data)    //前插入一个节点
{insert_front(plist->head,data);
}void insert_after(ListNode*  plist, intdata)     //链表头后插
{ListNode* cur =(ListNode*)malloc(sizeof(ListNode));ListNode* tem =plist->front; cur->data = data;plist->front = cur; //使链表头的头指针指向新插进来的节点cur->next = plist;  //新插进来的节点的尾指针指向链表头tem->next = cur;    //使tem节点的尾指针指向新插进来的节点cur->front = tem;   //新插进来的头指针指向tem
}void afterinsert_list(List* plist, int data) //后插入一个节点
{insert_after(plist->head,data);
}void  the_insert(List  *plist, int pos, int data)
{int i = 0;ListNode* cur =(ListNode*)malloc(sizeof(ListNode));ListNode* tem =plist->head;int num =data_num(plist);if (pos > num)//所插入数据的位置不能大于节点数,因为是循环链表{printf("插入数据失败\n");return;}for (; i < pos;i++){tem =tem->next;//找到插入新节点的位置}cur->data = data;cur->next =tem->next;//将tem尾指针中存放的内容赋给新节点的尾指针,即新节点的尾指针代替tem的尾指针tem->next->front= cur;//将原tem节点的下一个节点的头指针指向新节点cur->front = tem;//将新节点的头指针指向tem节点tem->next = cur;//将tem的尾指针指向新节点
}void print(List* plist)                   //打印
{ListNode* tem;if (plist->head ==NULL){printf("\n链表已销毁\n");return;}for (tem =plist->head->next; tem != plist->head; tem = tem->next)//双向循环链表的遍历{printf("%d  ", tem->data);}printf("\n");
}void  del(ListNode   *the_plist)       //删除
{the_plist->front->next= the_plist->next;//将该节点尾指针中存放的内容存放到上一个节点的尾指针中the_plist->next->front= the_plist->front;//将该节点头指针中存放的内容存放到下一个节点的头指针中free(the_plist);//释放这个节点
}void  del_front(List  *plist)    //头删
{del(plist->head->next);//删除链表头
} void  del_after(List  *plist)    //尾删
{del(plist->head->front);//删除链表尾
}ListNode* list_reach(List* plist, int data)     //查找
{ListNode* tem;for (tem =plist->head->next; tem != plist->head; tem = tem->next){if (tem->data== data)return  tem;}return NULL;
}void  the_del(List  *plist, int data)     //删除指定的节点
{ListNode* tmp =list_reach(plist, data);if (tmp)del(tmp);
}void  destory(List  *plist)      //销毁链表
{while (plist->head!= plist->head->next){del_front(plist);//依次删头}free(plist->head);//释放最后一个头plist->head = NULL;
}int main()
{//定义一个“链表头”List* first ;init(&first);forntinsert_list(&first,2);forntinsert_list(&first,8);print(&first);afterinsert_list(&first,0);print(&first);the_insert(&first,1, 5);print(&first);the_insert(&first,1, 6);print(&first);the_insert(&first,0, 9);print(&first);forntinsert_list(&first,0);print(&first);int k =data_num(&first);printf("%d个节点\n",k);the_insert(&first,8, 7);print(&first); del_after(&first);print(&first);del_front(&first);print(&first);the_del(&first,6);print(&first);system("pause");return 0;
}

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

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

相关文章

OkHttp透明压缩,收获性能10倍,外加故障一枚

要使用OkHttp&#xff0c;一定要知道它的透明压缩&#xff0c;否则死都不知道怎么死的&#xff1b;或者活也不知道为什么活的不舒坦。反正不是好事。什么叫透明压缩呢&#xff1f;OkHttp在发送请求的时候&#xff0c;会自动加入gzip请求头Accept-Encoding:gzip。所以&#xff0…

块元素、行内块和内联元素_如何删除内联块元素之间的空间?

块元素、行内块和内联元素Introduction: 介绍&#xff1a; This question has become rather popular. How does one remove whitespaces between the inline-block elements? The interesting thing is there are numerous solutions to this but not all of them are easy …

Spring--quartz中cronExpression 的配置方法

Spring--quartz中cronExpression Java代码 字段 允许值 允许的特殊字符 秒 0-59 , - * / 分 0-59 , - * / 小时 0-23 , - * / 日期 1-31 , - * ? / L W C 月份 1-12 或者 JAN-DEC , - * /…

C语言图形库——EasyX基本贴图

在C语言的学习过程中&#xff0c;接触最多的就是黑乎乎的DOS窗口&#xff0c;这也是在消磨学习者的兴趣&#xff0c;学到最后可能还不知道C语言到底能做什么&#xff0c;难道就是输入输出数据吗&#xff1f;当然不是&#xff0c;C的用处很广泛&#xff0c;这里不做讨论。我们能…

HTML5-特效

HTML5-特效-跟随鼠标的粒子<!DOCTYPE html> <html lang"en"><head><meta charsetutf-8><title>Liquid Particles - spielzeugz.de canvas experiment </title><meta name"description" content"HTML5/canvas …

一气之下,手撸了一个抖音去水印的工具!

百因必有果说一下我为什么要做个抖音视频去水印工具&#xff0c;其实是因为我的沙雕女友&#xff0c;她居然刚我~有天晚上她在抖音看见一个非常具有 教育意义 的视频&#xff0c;“男人疼媳妇就该承包全部家务活”&#xff0c;然后它就想把视频下载下来&#xff0c;分享到她的姐…

css 隐藏元素 显示元素_使用CSS打印时如何隐藏元素?

css 隐藏元素 显示元素Introduction: 介绍&#xff1a; We have come across many challenges while developing a website or web page and every challenge comes with new learnings. It is a trait of a good developer who develops or creates websites or web pages by…

C语言图形库——EasyX常用函数

上节讲到贴出一张图片的过程&#xff0c;本节接着介绍一些基本的图形库函数。 头文件 #include <graphics.h>1、图形窗口背景颜色设置函数&#xff1a; 例 setbkcolor(YELLOW)&#xff1b;//将图形窗口背景颜色设置为黄色。也可用 setbkcolor(RGB(180,24,137));利用三…

Adobe_Audition消除人声

傻瓜式: 方法一&#xff1a;效果 - 立体声声像 - 声道重混缩 - 选择Vocal Cut 新建左声道(左100;右-100) 新建右声道(左-100;右100;反相) 方法二&#xff1a;效果 - 立体声声像 - 析取中置通道 - Karaoke(效果预置) - 男声. (测试后&#xff0c;在傻瓜式中这种方法效果最好) 方…

Java新特性:数据类型可以扔掉了?

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;在很久很久以前&#xff0c;我们写代码时要慎重的考虑变量的数据类型&#xff0c;比如下面这些&#xff1a;枚举&#xff1a…

Spyder:Python中机器学习的强大武器

So, first of all, you would need to install Anaconda distribution which can be downloaded from the link https://www.anaconda.com/download/ (for Windows users only). 因此&#xff0c;首先&#xff0c;您需要安装Anaconda发行版 &#xff0c;可以从链接https://www.…

C语言+数据结构总结

一、C语言部分 1、数据类型&#xff1a; Int 整形 4字节Short 短整形 2字节Long 长整形 4字节Float 单精度浮点型 4字节Double 双精度浮点型 8字节Char 字符型 1字节2、变量 …

对内存重叠的深入认识

内存重叠&#xff1a;拷贝的目的地址在源地址范围内。所谓内存重叠就是拷贝的目的地址和源地址有重叠。在函数strcpy和函数memcpy都没有对内存重叠做处理的&#xff0c;使用这两个函数的时候只有程序员自己保证源地址和目标地址不重叠&#xff0c;或者使用memmove函数进行内存拷…

Android特效 五种Toast具体解释

Toast是Android中用来显示显示信息的一种机制&#xff0c;和Dialog不一样的是&#xff0c;Toast是没有焦点的&#xff0c;并且Toast显示的时间有限&#xff0c;过一定的时间就会自己主动消失。 1.默认效果: 代码:Toast.makeText(getApplicationContext(), "默认Toast样式&…

为什么阿里巴巴禁止使用BigDecimal的equals方法做等值比较?

△一个对Coding有着独特追求的人△作者 l Hollis来源 l Hollis&#xff08;ID&#xff1a;hollischuang&#xff09;BigDecimal&#xff0c;相信对于很多人来说都不陌生&#xff0c;很多人都知道他的用法&#xff0c;这是一种java.math包中提供的一种可以用来进行精确运算的类型…

日期getUTCMonth()方法以及JavaScript中的示例

JavaScript Date getUTCMonth()方法 (JavaScript Date getUTCMonth() method) getUTCMonth() method is a Dates class method and it is used to get the current month’s value according to the UTC (Universal time coordinated) between the range of 0 to 11, where 0 f…

VB另类技巧(可以用于VBA)-指针的使用

大家都知道C中可以使用指针&#xff0c;但现在VB&#xff08;当然也有VBA&#xff09;也可以使用指针了&#xff0c;这是我在网上看的一篇文章&#xff0c;大家参考一下。想当年东方不败&#xff0c;黑木崖密室一战&#xff0c;仅凭一根绣花针独战四大高手&#xff0c;神出鬼没…

动图演示:手撸堆栈的两种实现方法!

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;正式开始之前&#xff0c;先和各位朋友聊聊公众号后期的一些打算&#xff0c;后面的文章计划写一些关于数据结构和算法的内容…

Java中的异常处理

1 class YiChang{2 public static void main(String[] args){3 A anew A();4 a.show();5 }6 }7 8 class A{9 int[] i{1,2,3}; 10 public void show(){ 11 System.out.println(i[3]); 12 } 13 } 运行上面代码&#xff0c;会抛出这样…

数组copyWithin()方法以及JavaScript中的示例

JavaScript copyWithin()方法 (JavaScript copyWithin() method) copyWithin() method is used to copy the specified elements from an array and replace from specified index within the same array. It changes the this array (actual array). copyWithin()方法用于从数…