`

单循环链表的表示和实现

阅读更多
 /* bo2-4.c 设立尾指针的单循环链表(存储结构由c2-2.h定义)的12个基本操作 */
 Status InitList_CL(LinkList *L)
 { /* 操作结果:构造一个空的线性表L */
   *L=(LinkList)malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
   if(!*L) /* 存储分配失败 */
     exit(OVERFLOW);
   (*L)->next=*L; /* 指针域指向头结点 */
   return OK;
 }

 Status DestroyList_CL(LinkList *L)
 { /* 操作结果:销毁线性表L */
   LinkList q,p=(*L)->next; /* p指向头结点 */
   while(p!=*L) /* 没到表尾 */
   {
     q=p->next;
     free(p);
     p=q;
   }
   free(*L);
   *L=NULL;
   return OK;
 }

 Status ClearList_CL(LinkList *L) /* 改变L */
 { /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */
   LinkList p,q;
   *L=(*L)->next; /* L指向头结点 */
   p=(*L)->next; /* p指向第一个结点 */
   while(p!=*L) /* 没到表尾 */
   {
     q=p->next;
     free(p);
     p=q;
   }
   (*L)->next=*L; /* 头结点指针域指向自身 */
   return OK;
 }

 Status ListEmpty_CL(LinkList L)
 { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
   if(L->next==L) /* 空 */
     return TRUE;
   else
     return FALSE;
 }

 int ListLength_CL(LinkList L)
 { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
   int i=0;
   LinkList p=L->next; /* p指向头结点 */
   while(p!=L) /* 没到表尾 */
   {
     i++;
     p=p->next;
   }
   return i;
 }

 Status GetElem_CL(LinkList L,int i,ElemType *e)
 { /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
   int j=1; /* 初始化,j为计数器 */
   LinkList p=L->next->next; /* p指向第一个结点 */
   if(i<=0||i>ListLength_CL(L)) /* 第i个元素不存在 */
     return ERROR;
   while(j<i)
   { /* 顺指针向后查找,直到p指向第i个元素 */
     p=p->next;
     j++;
   }
   *e=p->data; /* 取第i个元素 */
   return OK;
 }

 int LocateElem_CL(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
 { /* 初始条件:线性表L已存在,compare()是数据元素判定函数 */
   /* 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。 */
   /*           若这样的数据元素不存在,则返回值为0 */
   int i=0;
   LinkList p=L->next->next; /* p指向第一个结点 */
   while(p!=L->next)
   {
     i++;
     if(compare(p->data,e)) /* 满足关系 */
       return i;
     p=p->next;
   }
   return 0;
 }

 Status PriorElem_CL(LinkList L,ElemType cur_e,ElemType *pre_e)
 { /* 初始条件:线性表L已存在 */
   /* 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */
   /*           否则操作失败,pre_e无定义 */
   LinkList q,p=L->next->next; /* p指向第一个结点 */
   q=p->next;
   while(q!=L->next) /* p没到表尾 */
   {
     if(q->data==cur_e)
     {
       *pre_e=p->data;
       return TRUE;
     }
     p=q;
     q=q->next;
   }
   return FALSE;
 }

 Status NextElem_CL(LinkList L,ElemType cur_e,ElemType *next_e)
 { /* 初始条件:线性表L已存在 */
   /* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */
   /*           否则操作失败,next_e无定义 */
   LinkList p=L->next->next; /* p指向第一个结点 */
   while(p!=L) /* p没到表尾 */
   {
     if(p->data==cur_e)
     {
       *next_e=p->next->data;
       return TRUE;
     }
     p=p->next;
   }
   return FALSE;
 }

 Status ListInsert_CL(LinkList *L,int i,ElemType e) /* 改变L */
 { /* 在L的第i个位置之前插入元素e */
   LinkList p=(*L)->next,s; /* p指向头结点 */
   int j=0;
   if(i<=0||i>ListLength_CL(*L)+1) /* 无法在第i个元素之前插入 */
     return ERROR;
   while(j<i-1) /* 寻找第i-1个结点 */
   {
     p=p->next;
     j++;
   }
   s=(LinkList)malloc(sizeof(struct LNode)); /* 生成新结点 */
   s->data=e; /* 插入L中 */
   s->next=p->next;
   p->next=s;
   if(p==*L) /* 改变尾结点 */
     *L=s;
   return OK;
 }

 Status ListDelete_CL(LinkList *L,int i,ElemType *e) /* 改变L */
 { /* 删除L的第i个元素,并由e返回其值 */
   LinkList p=(*L)->next,q; /* p指向头结点 */
   int j=0;
   if(i<=0||i>ListLength_CL(*L)) /* 第i个元素不存在 */
     return ERROR;
   while(j<i-1) /* 寻找第i-1个结点 */
   {
     p=p->next;
     j++;
   }
   q=p->next; /* q指向待删除结点 */
   p->next=q->next;
   *e=q->data;
   if(*L==q) /* 删除的是表尾元素 */
     *L=p;
   free(q); /* 释放待删除结点 */
   return OK;
 }

 Status ListTraverse_CL(LinkList L,void(*vi)(ElemType))
 { /* 初始条件:L已存在。操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */
   LinkList p=L->next->next;
   while(p!=L->next)
   {
     vi(p->data);
     p=p->next;
   }
   printf("\n");
   return OK;
 }

 

 /* main2-4.c 单循环链表,检验bo2-4.c的主程序 */
 #include"c1.h"
 typedef int ElemType;
 #include"c2-2.h"
 #include"bo2-4.c"

 Status compare(ElemType c1,ElemType c2)
 {
   if(c1==c2)
     return TRUE;
   else
     return FALSE;
 }

 void visit(ElemType c)
 {
   printf("%d ",c);
 }

 void main()
 {
   LinkList L;
   ElemType e;
   int j;
   Status i;
   i=InitList_CL(&L); /* 初始化单循环链表L */
   printf("初始化单循环链表L i=%d (1:初始化成功)\n",i);
   i=ListEmpty_CL(L);
   printf("L是否空 i=%d(1:空 0:否)\n",i);
   ListInsert_CL(&L,1,3); /* 在L中依次插入3,5 */
   ListInsert_CL(&L,2,5);
   i=GetElem_CL(L,1,&e);
   j=ListLength_CL(L);
   printf("L中数据元素个数=%d,第1个元素的值为%d。\n",j,e);
   printf("L中的数据元素依次为:");
   ListTraverse_CL(L,visit);
   PriorElem_CL(L,5,&e); /* 求元素5的前驱 */
   printf("5前面的元素的值为%d。\n",e);
   NextElem_CL(L,3,&e); /* 求元素3的后继 */
   printf("3后面的元素的值为%d。\n",e);
   printf("L是否空 %d(1:空 0:否)\n",ListEmpty_CL(L));
   j=LocateElem_CL(L,5,compare);
   if(j)
     printf("L的第%d个元素为5。\n",j);
   else
     printf("不存在值为5的元素\n");
   i=ListDelete_CL(&L,2,&e);
   printf("删除L的第2个元素:\n");
   if(i)
   {
     printf("删除的元素值为%d,现在L中的数据元素依次为:",e);
     ListTraverse_CL(L,visit);
   }
   else
     printf("删除不成功!\n");
   printf("清空L:%d(1: 成功)\n",ClearList_CL(&L));
   printf("清空L后,L是否空:%d(1:空 0:否)\n",ListEmpty_CL(L));
   printf("销毁L:%d(1: 成功)\n",DestroyList_CL(&L));
 }

 

分享到:
评论

相关推荐

    单循环链表(带头结点和不带头结点)

    总的来说,单循环链表是数据结构中的基础工具,理解和掌握其原理和实现方式对于学习更复杂的算法和数据结构至关重要。无论是带头结点还是不带头结点,都有其适用的场景和优缺点,开发者应根据具体需求选择合适的数据...

    Josephus问题C++单循环链表实现

    在提供的"Josephus"文件中,应该包含了上述步骤的具体实现,通过阅读和分析代码,我们可以深入理解Josephus问题的C++单循环链表解决方案。这个实现不仅满足了课本上的习题要求,也展示了如何将理论知识应用于实践。...

    约瑟夫环实验 建立单循环链表

    【约瑟夫环实验与单循环链表】 约瑟夫环问题是一个经典的...总的来说,这段代码通过单循环链表实现了约瑟夫环问题的模拟,其中涉及到了链表的插入、删除和遍历等基本操作,展示了数据结构在解决实际问题中的应用。

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

    约瑟夫环单循环链表的实现 在计算机科学中,约瑟夫环是一个经典的问题,该问题是指在一个圆圈中,n个人排成一圈,每个人都有一个密码,编号从1到n。现在,编号为m的密码将被点名,并将其从圆圈中删除,然后继续下一...

    循环链表、双链表及链表应用实验

    设计算法以判断一个带头结点的单循环链表是否满足...若成立,返回TRUE,否则返回FALSE,任务利用递增有序地单循环链表表示集合,分别求两个链表表示的集合的交、并集所构成的链表,设计算法以构造带头结点的双循环链表。

    单循环链表

    ### 单循环链表知识点详解 #### 一、单循环链表的概念与特点 单循环链表是一种特殊的线性表存储结构,它基于...以上就是单循环链表的相关知识点及具体实现细节,希望能帮助您更好地理解和掌握单循环链表这一数据结构。

    循环链表和双向链表

    总结来说,循环链表和双向链表是链表结构的两种不同类型,它们在数据结构与算法领域中占据着重要地位。通过理解这些链表结构的基本概念和操作方法,可以在实际的编程和应用开发中处理更复杂的数据关系和操作逻辑。

    创建有序的单循环链表,并合并两个有序的单循环链表,并返回的是尾结点

    合并有序单循环链表,不重新申请存储空间; 创建有序单循环链表,并指向尾结点; 新单循环链表的指针指向尾结点;

    约瑟夫环单循环链表C语言实现

    ### 约瑟夫环单循环链表C语言实现 #### 背景与问题描述 约瑟夫环(Josephus Problem)是一个经典的数学问题,最早由Flavius Josephus在公元前1世纪提出。该问题的基本形式是:N个人围成一个圈,从第一个人开始报数...

    单循环链表与约瑟夫问题模拟(java)

    通过理解和实现这个程序,你可以深入理解单循环链表的构造和操作,以及如何利用它来解决复杂的问题,如约瑟夫问题。这对于提高编程技巧和理解数据结构的应用至关重要。在实际开发中,类似的数据结构和算法可以用于...

    用C++做的单循环链表简单表示约瑟夫问题

    在这个问题的C++实现中,单循环链表是一种常见的数据结构选择。链表由一系列节点组成,每个节点包含数据和指向下一个节点的指针。单循环链表的特点是最后一个节点的指针会回指到链表的第一个节点,形成一个循环。 ...

    山东建筑大学 计算机科学与技术学院《数据结构》实验一:单循环链表的基本操作

    2、定义单循环链表类,并实现使用tail指向尾结点的单循环链表(有头结点)的创建、插入、删除、取元素操作和将单链表中的最小元素移到最前面的操作,以及迭代器; 3、从键盘上依次输入21、75、30、18、42、56,创建...

    假设以带头结点的循环链表表示一个队列,并且只设一个队尾指针指向尾元素结点(注意不设头指针),试写出相应的置空队、入队、出队的算法 (Java)

    假设以带头结点的循环链表表示一个队列,并且只设一个队尾指针指向尾元素结点(注意不设头指针),试写出相应的置空队、入队、出队的算法。(Java描述)

    将1个单链表变成3个单循环链表

    将一个单链表转换为三个单循环链表的过程涉及对链表节点的动态分配、遍历和分类。通过上述分析,我们可以看到,该任务不仅考验了对链表数据结构的理解,还要求掌握C语言中指针操作、条件判断和循环控制等技能。这一...

    VC++2012编程演练数据结构《2》单循环链表与约瑟夫问题

    VC++2012编程演练数据结构《2》单循环链表与约瑟夫问题

    编写算法依次访问无头结点的单循环链表.doc

    链表可以分为两种:带头结点的单循环链表和无头结点的单循环链表。今天,我们将讨论编写算法依次访问无头结点的单循环链表,并判断带头结点的单循环链表是否满足某些条件,以及求两个递增有序链表的交集和并集。 ...

    循环链表的逆置

    【循环链表的逆置】是指在数据结构中,对一个单循环链表进行操作,使其元素顺序反转。循环链表是一种特殊的链表,它的最后一个节点指针指向链表的第一个节点,形成一个闭环。逆置操作是将链表中的元素顺序颠倒,原先...

    单循环链表PPT学习教案.pptx

    这个函数实现了将两个已知尾结点的单循环链表连接成一个新链表的过程,其中`rearA`和`rearB`分别代表两个链表的尾结点。通过调整指针关系,新的链表头部保持了原有链表的顺序,而尾部则变成了`rearB`。 总的来说,...

    数据机构C语言用双向循环链表实现通讯簿

    在本课程设计中,学生被要求使用C语言来实现一个基于双向循环链表的通讯录系统。这个系统应具备添加、插入、删除、查询和统计联系人信息的基本功能,并且要具备良好的用户界面和错误处理机制,以确保系统的稳定性和...

Global site tag (gtag.js) - Google Analytics