1.基本操作

  • 循环链表的特点是最后一个元素的指针域指向头结点。

  • 因此对于循环链表的初始化(设表的头结点是L, 不再是L->next=NULL,而是L->next=L。循环链表为空时,头结点的下一个结点依然是头结点本身。因此但虚幻链表的初始化如下:
//初始化
int InitList(LinkList &L)
{L=new LNode;L->next=L;   //非循环链表的初始化是头指针的指针域置空 L->next=NULL return 1;
}
  • 从循环链表中的任何一个结点的位置都可以找到其他所有结点,而单链表做不到;
  • 循环链表中没有明显的尾端,如何避免死循环?
  • 循环条件:
    • p!=NULL  -—>  p!=L
    • p->next!=NULL ——>  p->next!=L
  • 所以根据循环链表的特点,判断循环链表是否为空时,只需判断头结点的下一个结点是否是头结点即可:
//判断链表是否为空
int ListEmpty(LinkList L)
{if(L->next==L){return 1;//空 }else{return 0;//非空 }
}
  • 从头检查每一个结点,若当前结点不是头结点,则链表长度加1,由此可计算链表的长度:
//获取链表长度
int ListLength(LinkList L)
{int length=0;LNode *p;p=L->next;while(p!=L){ //当p不是头结点时,链表长度加1 p=p->next;length++;}return length;
}
  • 遍历链表
//遍历链表
void TraveList(LinkList L)
{LNode *p;p=L->next;printf("遍历链表:\n");while(p!=L){      //当p不是头结点时,输出元素值 printf("%d ",p->data);p=p->next;}printf("\n");
}
  • 使用头插法和尾插法创建单循环链表的方法和创建一般单链表的操作一样,区别在于建立空链表的语句不同。一般单链表是L->next=NULL,而单循环链表是L->next=L。
  • 头插法
//头插法创建单循环链表
void CreateList1(LinkList &L,int n)
{//创建长度为n的单循环链表 L=new LNode;L->next=L;printf("请输入链表元素值:\n");for(int i=n;i>0;--i){printf("请输入第%d个元素的值:",i);LNode *p;p=new LNode;//生成新结点scanf("%d",&p->data);p->next=L->next;;L->next=p; }
}
  • 尾插法
//尾插法创建单循环链表
void CreateList2(LinkList &L,int n)
{L=new LNode;L->next=L;struct LNode *r;r=L;for(int i=0;i<n;i++){printf("请输入第%d个元素的值:",i+1);LNode *p;p=new LNode;scanf("%d",&p->data);p->next=L;r->next=p;r=p;}
}
  • 单循环链表的删除操作和一般单链表的操作时一样的。要注意的是单循环链表的插入操作:
//单循环链表的插入操作
int ListInsert(LinkList &L,int location,int &e)
{//在L的location位置插入元素eLNode *p;p=L;int j=0;while(p->next!=L&&j<location-1){//注意:由于p初始时指向头结点,所以循环的条件是 p->next!=L,而不是 p!=L p=p->next;                      j++;}if(p==L||j>location-1){return 0;}LNode *s;s=new LNode;s->data=e;s->next=p->next;p->next=s;return 1;
} 
  • 删除操作
//单循环链表的删除操作
int ListDelete(LinkList &L,int location,int &e)
{//删除L中location位置的元素,并用e返回其值LNode *p;p=L;int j=0;while(p->next!=L&&j<location-1){p=p->next;j++;}if(p==L||j>location-1){return 0;}LNode *q;q=new LNode;q=p->next;p->next=q->next;e=q->data;delete q;return 1;
}

2.代码实现

  • man.cpp
#include<iostream>using namespace std;//存储结构
typedef struct LNode
{int data;struct LNode *next;
}LNode, *LinkList;//初始化
int InitList(LinkList &L)
{L = new LNode;L->next = L;       //非循环链表的初始化是头指针的指针域置空 L->next=NULL return 1;
}// 判断链表是否为空
int ListEmpty(LinkList L)
{if (L->next == L){return 1;   // 空 }else {return 0;  // 非空 }
}// 获取链表长度
int ListLength(LinkList L)
{int length = 0;LNode *p;p = L->next;while (p != L){                  //当p不是头结点时,链表长度加1 p = p->next;length++;}return length;
}// 遍历链表
void TraveList(LinkList L)
{LNode *p;p = L->next;printf("遍历链表:\n");while (p != L) {                             //当p不是头结点时,输出元素值 printf("%d ", p->data);p = p->next;}printf("\n");
}// 头插法创建单循环链表
void CreateList1(LinkList &L, int n)
{//创建长度为n的单循环链表 L = new LNode;L->next = L;printf("请输入链表元素值:\n");for (int i = n; i > 0; --i){printf("请输入第%d个元素的值:", i);struct LNode *p;p = new LNode;//生成新结点scanf("%d", &p->data);p->next = L->next;;L->next = p;}
}// 尾插法创建单循环链表
void CreateList2(LinkList &L, int n)
{L = new LNode;L->next = L;struct LNode *r;r = L;printf("请输入链表元素值:\n");for (int i = 0; i < n; i++) {printf("请输入第%d个元素的值:", i + 1);LNode *p;p = new LNode;scanf("%d", &p->data);p->next = L;r->next = p;r = p;}
}//单循环链表的插入操作
int ListInsert(LinkList &L, int location, int &e)
{//在L的location位置插入元素eLNode *p;p = L;int j = 0;while (p->next != L && j < location - 1) {//注意:由于p初始时指向头结点,所以训话的条件是 p->next!=L //而不是 p!=L p = p->next;j++;}if (p == L || j > location - 1) {return 0;}LNode *s;s = new LNode;s->data = e;s->next = p->next;p->next = s;return 1;
}//单循环链表的删除操作
int ListDelete(LinkList &L, int location, int &e)
{//删除L中location位置的元素,并用e返回其值LNode *p;p = L;int j = 0;while (p->next != L && j < location - 1) {p = p->next;j++;}if (p == L || j > location - 1) {return 0;}LNode *q;//q = new LNode;q = p->next;p->next = q->next;e = q->data;delete q;return 1;
}int main()
{LinkList L;if (InitList(L)) {printf("初始化成功!\n");}else {printf("初始化失败!\n");}if (ListEmpty(L)) {printf("当前链表为空.\n");}else {printf("链表非空.\n");}printf("请输入链表长度:");int n;scanf("%d", &n);CreateList2(L, n);if (ListEmpty(L)) {printf("当前链表为空.\n");}else {printf("链表非空.\n");}printf("当前链表长度是:%d\n", ListLength(L));TraveList(L);printf("请输入插入位置和值:\n");int location, e;scanf("%d,%d", &location, &e);if (ListInsert(L, location, e)) {printf("插入成功\n");}else {printf("插入失败\n");}TraveList(L);printf("请输入删除元素的位置:\n");int e1, location1;scanf("%d", &location1);if (ListDelete(L, location1, e1)) {printf("删除成功\n");printf("删除的元素值为:%d\n", e1);}else {printf("删除失败\n");}TraveList(L);system("pause");return 0;
}
  • 运行结果

数据结构—带头结点的单循环链表相关推荐

  1. 数据结构--带头结点的单链表

    单链表分为:带头结点和不带头结点,不带头结点的单链表需要用到二级指针,容易出错. 1.结构体设计 typedef int ELEM_TYPE; //有效数据节点结构体设计(头结点借用) typedef ...

  2. 【C语言】数据结构C语言版 实验3 带头结点的单链表

    slnklist.h #include <stdio.h> #include <stdlib.h> /************************************* ...

  3. 【C语言】数据结构C语言版 实验2 不带头结点的单链表

    运行环境:Dev-C++ vs2013可能不能运行 首先新建一个头文件slnklist.h #include <stdio.h> #include <stdlib.h> /** ...

  4. 数据结构:假设有一个带头结点的单链表L,每个结点值由单个数字、小写字母和大写字母构成。设计一个算法将其拆分成3个带头结点的单链表L1、L2和L3,L1包含L中的所有数字结点,L2包含L中的所有小写字母

    假设有一个带头结点的单链表L,每个结点值由单个数字.小写字母和大写字母构成.设计一个算法将其拆分成3个带头结点的单链表L1.L2和L3,L1包含L中的所有数字结点,L2包含L中的所有小写字母结点,L3 ...

  5. 数据结构例9.编写一个算法,将带头结点的单向链表 拆分成一个奇数链表和一个偶数链表,并分别输出

    /* 编写一个算法,将带头结点的单向链表 拆分成一个奇数链表和一个偶数链表,并分别输出 */ # include <iostream> # include <stdlib.h> ...

  6. 不带头结点的单链表c语言,数据结构:C语言实现----不带头结点单链表总结

    不带头结点的单链表结构体声明 typedef struct Node { int data; struct Node *next; }Node, *LinkList; (1)初始化 void Init ...

  7. 算法与数据结构之带头结点的单链表

    单链表优缺点 链表是非随机存取的存储结构,和顺序表相比,链表存储结构在实现插入.删除的操作时,不需要移动大量数据元素(但不容易实现随机存取线性表的第 i 个数据元素的操作).所以,链表适用于经常需要进 ...

  8. 数据结构c/c++ 头插法尾插法建立带头结点的单链表,以数组创建带头结点的单链表和不带头结点的单链表,输出打印单链表

    // // Created by 焦娇 on 2021/9/17. //#ifndef CHAPTER2_LINELINK_LLK_H #define CHAPTER2_LINELINK_LLK_H# ...

  9. 头指针为head的带头结点的单链表判空条件head->next==null?

    由于考研需求,又乖乖滚回来捧起数据结构了,一年没碰书,忘得都差不多了,还得捡回来,哭死了. 进入正题,为何头指针为head的带头结点的单链表判空条件head->next==null?其实一开始这 ...

最新文章

  1. qlistview 自定义控件_是否可以在QListView中添加自定义窗口小部件?
  2. pyHook pyHook3 区别_一般过去时态和现在完成时态之间到底有什么区别?通过一道语法题,帮你彻底讲清楚!...
  3. js当前时间格式化_JS时间格式化
  4. Java复习-对象的回收与垃圾的回收
  5. JavaScript 函数基础
  6. linux版本i686,在Ubuntu中'i686'是什么意思? - Ubuntu问答
  7. Matlab神经网络基础
  8. 计算机远程操作之后怎么保护,电脑远程控制怎么操作 两种方法介绍
  9. mdf文件和ldf文件是什么?
  10. TX-LCN分布式事务之LCN模式
  11. k8s教程(pod篇)-污点与容忍
  12. 数据智能让天下没有难做的营销——友盟+首席运营官吕志国 确认出席第七届GDMS!...
  13. Tableau 群集部署
  14. Invalidate()函数
  15. Dell戴尔服务器添加新硬盘认不到解决方法
  16. 十款免费开源音频制作软件
  17. 计算机在物理学中应用论文3000字,大学物理论文3000字
  18. 基于springboot实现大学生租房系统演示【附项目源码】分享
  19. java学的什么软件_java初学者用什么软件
  20. 旅游社区如何吸引流量和留住用户?

热门文章

  1. buu做题笔记——[WUSTCTF2020]朴实无华[BSidesCF 2020]Had a bad day
  2. BugkuCTF-WEB-网站被黑
  3. djfpfp高温计算机电缆,DJFPFP高温计算机电缆
  4. 在使用单选、多选、下拉组件时,v-mode绑定的值的类型不准确引起显示报错注意
  5. 记账本NABCD分析
  6. 高大上的2014WE大会
  7. 国内较好的erp企业有哪些?
  8. Linux网络安全策略
  9. 2017_ASDL-GAN_Automatic Steganographic Disortion Learning Using a Generative Adversarial Network
  10. Cocos2D游戏初步