一、概念

循环链表是在一般链表的基础上,对链表的尾结点做改动,让其的next指针不指向NULL,而是改为指向头结点,从而让整个链表形成一个环。

二、定义

定义与一般链表没区别

三、代码实现

循环链表可以分成循环单链表和循环双链表,与不循环的代码的区别在于增加删减节点时对前驱后继的修改。

初始化时,头结点的next指针不再指向空而是换为指向自己。

使用头插法时,单循环链表与不循环没有区别,因为每次增加的节点相当于在链表的中间,并没有影响到后面的节点。双循环链表也是一个道理。

使用尾插法则有小小的变动,因为插入的节点在尾部,所以要插入的节点的next指针指向的要换成head头结点。

//单循环链表尾插法
void buttominsert(int n)
{for(int i=0;i<n;i++){struct LNode *temp;temp=(struct LNode*)malloc(sizeof(struct LNode));scanf("%d",&temp->num);temp->next=head;L->next=temp;L=L->next;head->num++;}
}
//双循环链表尾插法
void buttominsert(int n)
{for(int i=0;i<n;i++){struct LNode *temp;temp=(struct LNode*)malloc(sizeof(struct LNode));scanf("%d",&temp->num);temp->next=head;temp->pre=L;L->next=temp;L=L->next;head->num++;}
}

除此之外,在遍历链表时到表尾的条件也要做出修改,因为最后一个节点的next不再是空而是head。其余部分上实现起来和一般的单链表双链表没什么区别,主要还是因为变化根本就不大,修改的就只有最后一个节点而已。直接上手撸代码。

//循环单链表
#include<bits/stdc++.h>
using namespace std;
struct LNode{int num;struct LNode *next;
};
struct LNode *head;//头结点
struct LNode *L;//尾结点
void init()
{head=(struct LNode*)malloc(sizeof(struct LNode));L=head;head->next=head;head->num=0;
}
void print()
{struct LNode *out;out=head->next;while(out!=head){printf("%d ",out->num);out=out->next;}printf("\n");printf("The length of the list is %d\n",head->num);
}
void headinsert(int n)
{for(int i=0;i<n;i++){struct LNode *temp;temp=(struct LNode*)malloc(sizeof(struct LNode));scanf("%d",&temp->num);temp->next=head->next;head->next=temp;head->num++;}
}
void buttominsert(int n)
{for(int i=0;i<n;i++){struct LNode *temp;temp=(struct LNode*)malloc(sizeof(struct LNode));scanf("%d",&temp->num);temp->next=head;L->next=temp;L=L->next;head->num++;}
}
int search(int tar)
{int cnt=0;struct LNode *temp;temp=head->next;while(temp!=head){if(temp->num==tar)return cnt;cnt++;temp=temp->next;}return -1;
}
bool insert(int tar,int num)
{if(tar<0||tar>head->num)return false;struct LNode *temp;temp=(struct LNode*)malloc(sizeof(struct LNode));temp->num=num;struct LNode *p=head;while(tar--)p=p->next;temp->next=p->next;p->next=temp;head->num++;return true;
}
bool Delete(int tar)
{if(tar<0||tar>=head->num)return false;struct LNode *p,*q;p=head;while(tar--)p=p->next;q=p->next;p->next=p->next->next;free(q);head->num--;return true;
}
void delmode()
{int tar;printf("Input the location that you want to delete:");scanf("%d",&tar);if(!Delete(tar-1))printf("Delete failed\n");elseprintf("Delete succeed\n");
}
void insmode()
{int tar,num;printf("Input the location and num that you want to insert:");scanf("%d %d",&tar,&num);if(!insert(tar-1,num))printf("Insert failed\n");elseprintf("Insert succeed\n");
}
void seamode()
{int tar;printf("Input the number you want to search:");scanf("%d",&tar);int ans=search(tar);if(ans==-1)printf("Find failed\n");elseprintf("The target is at the %d\n",ans+1);
}
int main()
{init();int n,tar,num,choice=-1;printf("Input the amount of elements:");scanf("%d",&n);buttominsert(n);//headinsert(n);print();while(choice!=0){printf("1-delete\n");printf("2-insert\n");printf("3-show\n");printf("4-search\n");printf("0-exit\n");printf("Choice the function you want:");scanf("%d",&choice);switch(choice){case 1:delmode();break;case 2:insmode();break;case 3:print();break;case 4:seamode();break;case 0:break;default:printf("input error!");break;} }   return 0;}
//循环双链表
#include<bits/stdc++.h>
using namespace std;
struct LNode{int num;struct LNode *next;struct LNode *pre;
};
struct LNode *head;//头结点
struct LNode *L;//尾结点
void init()
{head=(struct LNode*)malloc(sizeof(struct LNode));L=head;head->next=head;head->pre=head;head->num=0;
}
void print()
{struct LNode *out;out=head->next;while(out!=head){printf("%d ",out->num);out=out->next;}printf("\n");printf("The length of the list is %d\n",head->num);
}
void headinsert(int n)
{for(int i=0;i<n;i++){struct LNode *temp;temp=(struct LNode*)malloc(sizeof(struct LNode));scanf("%d",&temp->num);temp->next=head->next;temp->pre=head;head->next=temp;head->num++;}
}
void buttominsert(int n)
{for(int i=0;i<n;i++){struct LNode *temp;temp=(struct LNode*)malloc(sizeof(struct LNode));scanf("%d",&temp->num);temp->next=head;temp->pre=L;L->next=temp;L=L->next;head->num++;}
}
int search(int tar)
{int cnt=0;struct LNode *temp;temp=head->next;while(temp!=head){if(temp->num==tar)return cnt;cnt++;temp=temp->next;}return -1;
}
bool insert(int tar,int num)
{if(tar<0||tar>head->num)return false;struct LNode *temp;temp=(struct LNode*)malloc(sizeof(struct LNode));temp->num=num;struct LNode *p=head;while(tar--)p=p->next;temp->next=p->next;temp->pre=p;p->next->next->pre=temp;p->next=temp;head->num++;return true;
}
bool Delete(int tar)
{if(tar<0||tar>=head->num)return false;struct LNode *p,*q;p=head;while(tar--)p=p->next;q=p->next;p->next=p->next->next;p->next->pre=p;free(q);head->num--;return true;
}
void delmode()
{int tar;printf("Input the location that you want to delete:");scanf("%d",&tar);if(!Delete(tar-1))printf("Delete failed\n");elseprintf("Delete succeed\n");
}
void insmode()
{int tar,num;printf("Input the location and num that you want to insert:");scanf("%d %d",&tar,&num);if(!insert(tar-1,num))printf("Insert failed\n");elseprintf("Insert succeed\n");
}
void seamode()
{int tar;printf("Input the number you want to search:");scanf("%d",&tar);int ans=search(tar);if(ans==-1)printf("Find failed\n");elseprintf("The target is at the %d\n",ans+1);
}
int main()
{init();int n,tar,num,choice=-1;printf("Input the amount of elements:");scanf("%d",&n);buttominsert(n);//headinsert(n);print();while(choice!=0){printf("1-delete\n");printf("2-insert\n");printf("3-show\n");printf("4-search\n");printf("0-exit\n");printf("Choice the function you want:");scanf("%d",&choice);switch(choice){case 1:delmode();break;case 2:insmode();break;case 3:print();break;case 4:seamode();break;case 0:break;default:printf("input error!");break;} }   return 0;}

四、优缺点分析

因为循环链表是个环,所以头结点的意义会稍微有点模糊,因为从任意一个节点都可以访问到全部节点,所以从这个角度看,头结点的意义会不那么明显,除此之外,头指针也可以取消,只留一个尾指针即可,这是因为其循环的缘故,尾指针的下一个就成了头指针所指向的头结点,这样操作起来就更加高效。若设的是头指针,对表尾进行操作需要 O(n)的时间复杂度,而若设的是尾指针 next 即为头指针, 对于表头与表尾进行操 作都只需要 O(1)的时间复杂度。

数据结构 2-3-3 循环链表相关推荐

  1. C语言中链表的英文名字,数据结构C语言版 循环链表表示和实现(国外英文).doc

    数据结构C语言版 循环链表表示和实现(国外英文) 数据结构C语言版 循环链表表示和实现(国外英文资料) Data structure, C language, circular list repres ...

  2. 初阶数据结构之带头+双向+循环链表增删查实现(三)

    文章目录 @[TOC](文章目录) 前言 一.带头双向循环链表的初始化 1.1带头双向循环链表的结构体定义 1.2初始化代码的实现 二.带头+双向+循环链表的增功能实现 2.1头插代码的实现 2.2尾 ...

  3. 数据结构(六)——循环链表

    数据结构(六)--循环链表 一.循序链表简介 1.循环链表的定义 循环链表的任意元素都有一个前驱和一个后继,所有数据元素在关系上构成逻辑上的环. 循环链表是一种特殊的单链表,尾结点的指针指向首结点的地 ...

  4. 数据结构:带头双向循环链表——增加、删除、查找、修改,详细解析

    读者可以先阅读这一篇:数据结构--单链表的增加.删除.查找.修改,详细解析_昵称就是昵称吧的博客-CSDN博客,可以更好的理解带头双向循环链表. 目录 一.带头双向循环链表的处理和介绍 1.带头双向循 ...

  5. 数据结构一:链表(循环链表)

    一:实现机制 Linux链表实现思想就是:结点里面只创建一个next指针,用指针将各个结点相连接 打印和查找的时候,再进行类型的转换. 循环链表在Linux链表的基础上改动,最后结点的next指向的是 ...

  6. 数据结构基础(12) --双向循环链表的设计与实现

    双向链表的操作特点: (1) "查询" 和单链表相同; (2)"插入" 和"删除"时需要同时修改两个方向上的指针. 但是对于双向循环链表则在 ...

  7. 【数据结构】带头双向循环链表

    各位读者们好久不见了,咋们接着上一期链表来,今天来实现一下链表最难的结构,同时也是实现起来最简单的结构--带头双向循环链表.话不多说,进入主题 文章目录 前言 实现带头双向循环链表 DList.h头文 ...

  8. 【数据结构】双向单链循环链表

    文章目录 前言 一.结构简介 二.具体代码 总结 前言 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.链表由一系列节点组成,节点可以动态增加或者 ...

  9. 【数据结构】带头+双向+循环链表的 增,删,查,改 的实现

    #include <iostream>using namespace std;int main() {typedef int ListType;typedef struct ListNod ...

  10. 【数据结构】三、循环链表

    1.循环链表的定义 循环链表是一种头尾相接的链表,表中最后一个结点的指针域指向头结点,整个链表形成一个环. 2.循环链表的优点 从表中任一结点出发均可找到表中其他结点 3.循环链表的遍历终止条件 由于 ...

最新文章

  1. mysql thread safe_Windows环境下完全手工配置Apache、MySQL和PHP(Thread Safe)
  2. Spring Cloud Alibaba 一致性挑战:微服务架构下的数据一致性解决方案
  3. php系统升级说明,PHPCMF内容管理框架 v4.2.7 升级说明
  4. Privatization of Roads in Treeland
  5. Oracle从零开始3——复杂查询
  6. 雷军微博抽奖送的那台蔚来ES6 时隔10个月终于提到车了
  7. 数据结构笔记(三十六)-- 插入排序与直接插入排序
  8. hadoop集群环境配置成功与否查看方法
  9. 加载等待loading
  10. pnp型三极管 饱和 截至_截至2013年核心Java帖子
  11. 服务器每个月维护要1000元,5月24日服务器例行维护公告(已完成)
  12. WINRAR弹出激活框解决
  13. proteus8.9仿真闪退怎么解决?如何找到ProgramData?
  14. 考研时间安排和考研内容
  15. html5 spin,HTML5 number spinbox controls not triggering a cha
  16. uniapp调用android原生方法
  17. 【mysql】mysql数据备份与恢复
  18. MPC模型预测控制及在Matlab中实现函数定义
  19. masonry Unable to simultaneously satisfy constraints. Probably at least one of the c
  20. 威联通nas怎么更换大硬盘_更换NAS后,数据如何安全处理?聊聊NAS数据安全性那些事...

热门文章

  1. php练习——打印半金字塔、金字塔、空心金字塔、菱形、空心菱形
  2. 从文档流角度理解浏览器页面渲染引擎对元素定位的解析
  3. 用户在登录的时候,密码输入错误也能登录问题
  4. 面向对象的JavaScript-007-Function.prototype.bind() 的4种作用
  5. 结对编程后传之做汉堡
  6. 引用和指针的区别[zz]
  7. 分享基于silverlight的一个大文件上传控件
  8. css + div + js 制作HTML tab control
  9. 《设计模式详解》创建型模式 - 工厂模式
  10. 从零开始带你部署springboot项目到ubuntu服务器05