循环链表是还有一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。

循环链表的操作
1,循环链表的新操作
2, 获取当前游标指向的数据元素
3, 将游标重置指向链表中的第一个数据元素

4,将游标移动指向到链表中的下一个数据元素

5,直接指定删除链表中的某个数据元素

CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node);
CircleListNode* CircleList_Reset(CircleList* list);
CircleListNode* CircleList_Current(CircleList* list);
CircleListNode* CircleList_Next(CircleList* list);

头文件:

#ifndef _CIRCLE_H_
#define _CIRCLE_H_
//採用数据封装的方式。防止在主函数改动当中的属性值(有点点像面向对象中的私有属性)
typedef void CircleList;
typedef struct CircleListNode //声明指针域
{
CircleListNode * next;
}CircleListNode; CircleList * CircleList_Create(); void CircleList_DesTroy(CircleList * list); void CircleList_Clear(CircleList* list); int CircleList_Length(CircleList* list); int CircleList_Insert(CircleList* list, CircleListNode* node, int pos); CircleListNode* CircleList_Get(CircleList* list, int pos); CircleListNode* CircleList_Delete(CircleList* list, int pos); CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node); CircleListNode* CircleList_Reset(CircleList* list); CircleListNode* CircleList_Current(CircleList* list); CircleListNode* CircleList_Next(CircleList* list) ; #endif

源文件:

// 循环链表.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <malloc.h>
#include <stdlib.h>
#include "CircleList.h" typedef struct //定义头结点
{
CircleListNode header;
CircleListNode* sLider; //游标
int len;
}TCircleList; struct Value //定义数据结构体类型
{ CircleListNode header; //指针域
int v; //数据域
}; int _tmain(int argc, _TCHAR* argv[])
{ int i = 0;
CircleList* list = CircleList_Create(); struct Value v1;
struct Value v2;
struct Value v3;
struct Value v4;
struct Value v5;
struct Value v6;
struct Value v7;
struct Value v8; v1.v = 1;
v2.v = 2;
v3.v = 3;
v4.v = 4;
v5.v = 5;
v6.v = 6;
v7.v = 7;
v8.v = 8; CircleList_Insert(list, (CircleListNode*)&v1, CircleList_Length(list));
CircleList_Insert(list, (CircleListNode*)&v2, CircleList_Length(list));
CircleList_Insert(list, (CircleListNode*)&v3, CircleList_Length(list));
CircleList_Insert(list, (CircleListNode*)&v4, CircleList_Length(list));
//插入到 5 的位置,前面的顺序为 1->2->3->4
// 下标: 0 1 2 3
// 4 5 ...
//故而插入到 5 的位置时 打印的结果应为 : 1,5,2,3,4。后面的结果也验证了其正确性
CircleList_Insert(list, (CircleListNode*)&v5, 5); for(i=0; i<CircleList_Length(list); i++)
{
struct Value* pv = (struct Value*)CircleList_Get(list, i); printf("%d\n", pv->v);
} while( CircleList_Length(list) > 0 )
{
struct Value* pv = (struct Value*)CircleList_Delete(list, 0); printf("删除了:%d\n", pv->v);
} CircleList_DesTroy(list); system("pause");
return 0;
} //创建
CircleList * CircleList_Create()
{
TCircleList* list = (TCircleList*)malloc(sizeof(TCircleList));
if(NULL != list)
{
list->sLider = NULL;
list->header.next = NULL;
list->len = 0; }
return list;
} //销毁
void CircleList_DesTroy(CircleList * list)
{
free(list);
}
//清空
void CircleList_Clear(CircleList* list)
{
TCircleList * sList = (TCircleList*)list;
if(NULL != sList)
{
sList->len = 0;
sList->header.next = NULL;
sList->sLider = NULL;
}
}
//获得长度
int CircleList_Length(CircleList* list)
{
TCircleList * sList = (TCircleList*)list;
int len = -1;
if(NULL != sList)
{
len = sList->len;
}
return len;
}
//插入  
int CircleList_Insert(CircleList* list, CircleListNode* node, int pos)  
{  
TCircleList * sList = (TCircleList*)list;  
int i = 0;  
int ret = 0;  
sList->len;  
if((NULL != sList) && (pos>=0) && (NULL != node))  
{  
    CircleListNode * current = (CircleListNode*)sList;  
    for ( i=0; i<pos && current->next != NULL; i++)  
    {  
    current = current->next;  
    }  
      
    node->next = current->next;         
    current->next = node;  
    if(sList->len == 0)  
    {  
    sList->sLider = node;  
      
    }  
    ++(sList->len);  
    if( current == (CircleListNode*)sList )  
    {  
    CircleListNode* last = CircleList_Get(sList, sList->len - 1);              
    last->next = current->next;  
    }  
    ret = 1;  
      
      
}  
return ret;  
}  //获得结点
CircleListNode* CircleList_Get(CircleList* list, int pos)
{
TCircleList * sList = (TCircleList*)list;
CircleListNode * resNode = NULL;
int i = 0;
if((NULL != sList) && (pos>=0))
{
CircleListNode * current = (CircleListNode*)sList;
for( i=0; i<pos; i++)
{
//i=0时,current为头结点,current->next为真正的第一个结点
current = current->next;
}
resNode = current->next;
}
return resNode;
} //删除
CircleListNode* CircleList_Delete(CircleList* list, int pos)
{
TCircleList * sList = (TCircleList*)list;
int i = 0;
CircleListNode * resnode = NULL;
CircleListNode* first = sList->header.next;
CircleListNode* last = (CircleListNode*)CircleList_Get(list,sList->len-1);
if((NULL != sList) && (pos >= 0) && (pos < sList->len))
{
CircleListNode * current = (CircleListNode*)sList;
for ( i=0; i<pos; i++)
{
//i=0时,current为头结点,current->next为真正的第一个结点
current = current->next;
}
resnode = current->next;
current->next = resnode->next; if(first == resnode)
{
sList->header.next = first->next;
last->next = first->next;
}
if(sList->sLider == resnode)
{
sList->sLider = resnode->next;
}
if(sList->len == 0)
{
sList->header.next = NULL;
sList->sLider = NULL;
}
}
sList->len--;
return resnode;
} //依据结点来删除
CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node)
{
TCircleList * sList = (TCircleList*)list;
CircleListNode* resnode = NULL;
int i = 0;
if(NULL != sList)
{
CircleListNode* current = (CircleListNode*)sList;
for ( i=0; i<sList->len; i++)
{
if(node == current->next)
{
resnode = current->next;
break;
}
current = current->next;
}
if(NULL != resnode)
{
CircleList_Delete(sList,i);
}
}
return resnode;
} //将游标重置回第一个元素
CircleListNode* CircleList_Reset(CircleList* list)
{
TCircleList* sList = (TCircleList*)list;
CircleListNode* ret = NULL; if( sList != NULL )
{
sList->sLider= sList->header.next;
ret = sList->sLider;
} return ret;
} //获得当前游标下的结点
CircleListNode* CircleList_Current(CircleList* list)
{ TCircleList* sList = (TCircleList*)list;
CircleListNode* ret = NULL;
sList->len;
sList->header;
sList->sLider;
if( sList != NULL )
{
ret = sList->sLider;
} return ret;
} //将游标移到下一个结点并获得当前移动前的结点
CircleListNode* CircleList_Next(CircleList* list)
{
TCircleList* sList = (TCircleList*)list;
CircleListNode* ret = NULL; if( (sList != NULL) && (sList->sLider != NULL) )
{
ret = sList->sLider;
sList->sLider = ret->next;
} return ret;
}

执行结果:

1
5
2
3
4
删除了:1
删除了:5
删除了:2
删除了:3
删除了:4
请按随意键继续. . .

如有错误,望不吝指出。

循环链表的实现与操作(C语言实现)的更多相关文章

  1. neo4j初次使用学习简单操作-cypher语言使用

    Neo4j 使用cypher语言进行操作 Cypher语言是在学习Neo4j时用到数据库操作语言(DML),涵盖对图数据的增删改查  neo4j数据库简单除暴理解的概念: Neo4j中不存在表的概念, ...

  2. 栈的实现与操作(C语言实现)

    栈的定义  1, 栈是一种特殊的线性表  2,栈仅能在线性表的一端进行操作  3,栈顶(Top): 同意操作的一端 同意操作的一端  4,栈底(Bottom): ,不同意操作的一端 不同意操作 ...

  3. 动态单链表的传统存储方式和10种常见操作-C语言实现

    顺序线性表的优点:方便存取(随机的),特点是物理位置和逻辑为主都是连续的(相邻).但是也有不足,比如:前面的插入和删除算法,需要移动大量元素,浪费时间,那么链式线性表 (简称链表) 就能解决这个问题. ...

  4. Gremlin--一种支持对图表操作的语言

    Gremlin 是操作图表的一个非常有用的图灵完备的编程语言.它是一种Java DSL语言,对图表进行查询.分析和操作时使用了大量的XPath. Gremlin可用于创建多关系图表.因为图表.顶点和边 ...

  5. 动态分配的顺序线性表的十五种操作—C语言实现

    线性表 定义:是最常用的,也是最简单的数据结构,是长度为n个数据元素的有序的序列. 含有大量记录的线性表叫文件 记录:稍微复杂的线性表里,数据元素为若干个数据项组成,这时把一个数据元素叫记录 结构特点 ...

  6. 双向链表的实现与操作(C语言实现)

    双向链表也叫双链表,是链表的一种,它的每一个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的随意一个结点開始,都能够非常方便地訪问它的前驱结点和后继结点. 单链表的局限 1.单 ...

  7. 图的存储结构与操作--C语言实现

    图(graph)是一种比树结构还要复杂的数据结构,它的术语,存储方式,遍历方式,用途都比较广,所以如果想要一次性完成所有的代码,那代码会非常长.所以,我将分两次来完成图的代码.这一次,我会完成图的五种 ...

  8. 二叉树的操作--C语言实现

    树是一种比较复杂的数据结构,它的操作也比较多.常用的有二叉树的创建,遍历,线索化,线索化二叉树的遍历,这些操作又可以分为前序,中序和后序.其中,二叉树的操作有递归与迭代两种方式,鉴于我个人的习惯,在这 ...

  9. C文件操作的语言fgets()

        谈fgets(..)功能.     原型  char *  fgets(char * s, int n,FILE *stream);     參数:          s: 字符型指针.指向存 ...

随机推荐

  1. 使用 JMeter 完成常用的压力测试 [转]

    讲到测试,人们脑海中首先浮现的就是针对软件正确性的测试,即常说的功能测试.但是软件仅仅只是功能正确是不够的.在实际开发中,还有其它的非功能因素也起着决定性的因素,例如软件的响应速度.影响软件响应速度的 ...

  2. MathType出现乱码公式怎么恢复

    在我们平时使用word上的数学公式编辑器的时候,有时一些公式会出现乱码的问题.这个时候可以改为使用MathType时,那么MathType出现乱码公式怎么恢复呢?如果只是少量公式可以手动重新输入,如果 ...

  3. spring配置文件中bean标签

    <bean id="beanId"(1) name="beanName"(2) class="beanClass"(3) parent ...

  4. usb摄像头的检测

    下面写一下过程: 如果你能在http://www.ideasonboard.org/uvc/找到你的摄像头的ID,即UVC支持的,那么就可以在linux下使用了.至于从哪个版本开始内核支持UVC,官方 ...

  5. [ACM] poj 2017 Speed Limit

    Speed Limit Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 17030   Accepted: 11950 Des ...

  6. Linux netstat 命令

    1. netstat命令用于显示系统的网络信息,包括网络连接 .路由表 .接口状态2. 一般我们使用 netstat 来查看本机开启了哪些端口,查看有哪些客户端连接 常见用法如下: [root@loc ...

  7. 制作Windows U盘镜像

    目的:制作windows server 2008 U盘镜像 需要的共具: 1.一个格式为FAT并且至少4G的U盘, 2.UltraISO软件, 3.一个windows server 2008 ISO文 ...

  8. m2014-architecture-imgserver->配置lighttpd mod_mem_cache 模块做静态资源服务器

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://freehat.blog.51cto.com/1239536/989171 一 l ...

  9. vue中的小踩坑(01)

    前言: 昨天算是使用vue2.0+element-ui做了一点小小的页面,可是源于其中遇到的问题,特地整理一下,以防自己还有其他的小伙伴们继续踩坑. 过程:         1.不知道大家有没有注意到 ...

  10. 什么叫做hack

    由于不同的浏览器,比如Internet Explorer 6,Internet Explorer 7,Mozilla Firefox等,对CSS的解析认识不一样,因此会导致生成的页面效果不一样,得不到 ...