02循环单链表

循环单链表定义:将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成了

        一个环,这种头尾相接的单链表成为单循环链表。

循环链表的数据结构:

1 /* c2-2.h 线性表的单链表存储结构 */
2 struct LNode
3 {
4     ElemType data;
5     struct LNode *next;
6 };
7 typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */

代码实现:

  1
  2
  3 /* bo2-4.c 设立尾指针的单循环链表(存储结构由c2-2.h定义)的12个基本操作 */
  4  Status InitList_CL(LinkList *L)
  5  {
  6      /* 操作结果:构造一个空的线性表L */
  7    *L=(LinkList)malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
  8    if(!*L) /* 存储分配失败 */
  9      exit(OVERFLOW);
 10    (*L)->next=*L; /* 指针域指向头结点 */
 11    return OK;
 12  }
 13
 14  Status DestroyList_CL(LinkList *L)
 15  {
 16      /* 操作结果:销毁线性表L */
 17    LinkList q,p=(*L)->next; /* p指向头结点 */
 18    while(p!=*L) /* 没到表尾 */
 19    {
 20      q=p->next;
 21      free(p);
 22      p=q;
 23    }
 24    free(*L);
 25    *L=NULL;
 26    return OK;
 27  }
 28
 29  Status ClearList_CL(LinkList *L) /* 改变L */
 30  {
 31      /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */
 32    LinkList p,q;
 33    *L=(*L)->next; /* L指向头结点 */
 34    p=(*L)->next; /* p指向第一个结点 */
 35    while(p!=*L) /* 没到表尾 */
 36    {
 37      q=p->next;
 38      free(p);
 39      p=q;
 40    }
 41    (*L)->next=*L; /* 头结点指针域指向自身 */
 42    return OK;
 43  }
 44
 45  Status ListEmpty_CL(LinkList L)
 46  {
 47      /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
 48    if(L->next==L) /* 空 */
 49      return TRUE;
 50    else
 51      return FALSE;
 52  }
 53
 54  int ListLength_CL(LinkList L)
 55  {
 56      /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
 57    int i=0;
 58    LinkList p=L->next; /* p指向头结点 */
 59    while(p!=L) /* 没到表尾 */
 60    {
 61      i++;
 62      p=p->next;
 63    }
 64    return i;
 65  }
 66
 67  Status GetElem_CL(LinkList L,int i,ElemType *e)
 68  {
 69      /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
 70    int j=1; /* 初始化,j为计数器 */
 71    LinkList p=L->next->next; /* p指向第一个结点 */
 72    if(i<=0||i>ListLength_CL(L)) /* 第i个元素不存在 */
 73      return ERROR;
 74    while(j<i)
 75    {
 76        /* 顺指针向后查找,直到p指向第i个元素 */
 77      p=p->next;
 78      j++;
 79    }
 80    *e=p->data; /* 取第i个元素 */
 81    return OK;
 82  }
 83
 84  int LocateElem_CL(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
 85  {
 86      /* 初始条件:线性表L已存在,compare()是数据元素判定函数 */
 87    /* 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。 */
 88    /*           若这样的数据元素不存在,则返回值为0 */
 89    int i=0;
 90    LinkList p=L->next->next; /* p指向第一个结点 */
 91    while(p!=L->next)
 92    {
 93      i++;
 94      if(compare(p->data,e)) /* 满足关系 */
 95        return i;
 96      p=p->next;
 97    }
 98    return 0;
 99  }
100
101  Status PriorElem_CL(LinkList L,ElemType cur_e,ElemType *pre_e)
102  {
103      /* 初始条件:线性表L已存在 */
104    /* 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */
105    /*           否则操作失败,pre_e无定义 */
106    LinkList q,p=L->next->next; /* p指向第一个结点 */
107    q=p->next;
108    while(q!=L->next) /* p没到表尾 */
109    {
110      if(q->data==cur_e)
111      {
112        *pre_e=p->data;
113        return TRUE;
114      }
115      p=q;
116      q=q->next;
117    }
118    return FALSE;
119  }
120
121  Status NextElem_CL(LinkList L,ElemType cur_e,ElemType *next_e)
122  {
123      /* 初始条件:线性表L已存在 */
124    /* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */
125    /*           否则操作失败,next_e无定义 */
126    LinkList p=L->next->next; /* p指向第一个结点 */
127    while(p!=L) /* p没到表尾 */
128    {
129      if(p->data==cur_e)
130      {
131        *next_e=p->next->data;
132        return TRUE;
133      }
134      p=p->next;
135    }
136    return FALSE;
137  }
138
139  Status ListInsert_CL(LinkList *L,int i,ElemType e) /* 改变L */
140  {
141      /* 在L的第i个位置之前插入元素e */
142    LinkList p=(*L)->next,s; /* p指向头结点 */
143    int j=0;
144    if(i<=0||i>ListLength_CL(*L)+1) /* 无法在第i个元素之前插入 */
145      return ERROR;
146    while(j<i-1) /* 寻找第i-1个结点 */
147    {
148      p=p->next;
149      j++;
150    }
151    s=(LinkList)malloc(sizeof(struct LNode)); /* 生成新结点 */
152    s->data=e; /* 插入L中 */
153    s->next=p->next;
154    p->next=s;
155    if(p==*L) /* 改变尾结点 */
156      *L=s;
157    return OK;
158  }
159
160  Status ListDelete_CL(LinkList *L,int i,ElemType *e) /* 改变L */
161  {
162      /* 删除L的第i个元素,并由e返回其值 */
163    LinkList p=(*L)->next,q; /* p指向头结点 */
164    int j=0;
165    if(i<=0||i>ListLength_CL(*L)) /* 第i个元素不存在 */
166      return ERROR;
167    while(j<i-1) /* 寻找第i-1个结点 */
168    {
169      p=p->next;
170      j++;
171    }
172    q=p->next; /* q指向待删除结点 */
173    p->next=q->next;
174    *e=q->data;
175    if(*L==q) /* 删除的是表尾元素 */
176      *L=p;
177    free(q); /* 释放待删除结点 */
178    return OK;
179  }
180
181  Status ListTraverse_CL(LinkList L,void(*vi)(ElemType))
182  {
183      /* 初始条件:L已存在。操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */
184    LinkList p=L->next->next;
185    while(p!=L->next)
186    {
187      vi(p->data);
188      p=p->next;
189    }
190    printf("\n");
191    return OK;
192  }
时间: 2024-08-24 23:21:04

02循环单链表的相关文章

循环单链表

//函数声明部分:#include"CirLinkList.h" #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> typedef int ElemType; typedef struct linknode { ElemType data; struct linknode *next; }node; void judgement_NULL(node * p); node 

c语言循环单链表

/************************************************************************* > File Name: singleLineTable.c > Author: zshh0604 > Mail: [email protected] > Created Time: 2014年10月15日 星期三 11时34分08秒 **************************************************

_DataStructure_C_Impl:循环单链表

//CycList:循环单链表 #include<stdio.h> #include<stdlib.h> typedef int DataType; typedef struct Node{ DataType data; struct Node *next; }ListNode,*LinkList; //创建一个不带头结点的循环单链表 LinkList CreateCycList(int n){ DataType e; LinkList head=NULL; ListNode *p

用循环单链表实现约瑟夫环

题目:n个人编号分别是1,2,3,...,n,围坐在一张圆桌周围,从编号为k的人开始报数,数到m的人出列.然后他的下一个人开始报数,数到m的那个人又出列:依次循环,直到所有人出列. struct LNode{ int data; LNode *next; }; //n为总人数,k为第一个开始报数的人,m为出列者喊到的数 void solve(int k,int m, int n) { if(k>n || n<=0 || m<=0) { throw "Invalid argume

【C语言数据结构】循环单链表

CircleLinkList.h #ifndef CIRCLE_LINK_LIST #define CIRCLE_LINK_LIST //链表节点 typedef struct _CircleLinkListNode {     struct _CircleLinkListNode *next; }CircleLinkListNode; //循环单链表 typedef void CircleLinkList; /*  * 创建循环单链表  * @return 返回循环单链表的指针  */ Cir

【线性表5】线性表的链式实现:循环单链表

简介 循环单链表 是在在单链表的基础上,用最后的一个结点的指针域指向头结点形成的.因此它在逻辑上是一个环形结构. 循环单链表在实际编程中很少用. 要点:1.遍历结束的标志是 p == [头结点地址],而不是p==NULL 2.表为空的判断标志是:   if( head->next == head   ) 3.在单循环链表中,从任一结点出发都可访问到表中所有结点 循环链表一般还使用尾指针rear保存最后一个结点的地址,因为使用尾指针既可以快速找到 最后一个结点,也可以快速找到头结点. 简单的代码实

【c++版数据结构】之循环单链表的实现(带头结点以及尾节点)

所实现的循环单链表的结构如下图所示: 循环单链表的实现,和上一篇文章单链表的实现大致相同点击打开链接,略有区别: 1:循环判断的条件不再是s == NULL或者s->next == NULL,而是他们是否等于头指针.2: 断开链表时的处理,尾节点的next不是NULL,而是指向头结点 具体细节参考上一篇文章 头文件:SCList.h #ifndef SCLIST_H #define SCLIST_H #include<iostream> #include<cassert> u

循环单链表,解决约瑟夫问题

约瑟夫问题: 编号为1~N的N个人按顺时针方向围坐一圈,每人持有一个密码(正整数),开始任选一个正整数作为报数上限值M,从第1个人按顺时针方向自1开始顺序报数,报到M时停止报数.报M的人出列,将他的密码作为新的M值,从他顺时针方向上的下一个人开始从1报数,如此下去,直至所有人全部出列为止. 解析: 显然当有人退出圆圈后,报数的工作要从下一个人开始继续,而剩下的人仍然围成一个圆圈,因此可以使用循环单链表.退出圆圈的工作对应着表中节点的删除操作,对于这种删除操作频繁的情况,选用效率较高的链表结构,为

数据结构之自建算法库——循环单链表

本文针对数据结构基础系列网络课程(2):线性表中第13课时双链表. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 双链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:clinklist.h,包含定义双链表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef CLINKLIST_H_INCLUDED #define CLINKLIST_H_INCLUDED //循环单链表基本运算函数 typedef int ElemT