循环链表的C风格实现(单向)
头文件:
#ifndef _CIRCLELIST_H_
#define _CIRCLELIST_H_
typedef void CircleList; // typedef struct _tag_CircleListNode
{
struct _tag_CircleListNode* next;
}CircleListNode; //创建一个循环链表
CircleList* CircleList_Create();
//删除一个循环链表
void CircleList_Destroy(CircleList* list);
//清空一个循环链表
void CircleList_Clear(CircleList* list);
//返回链表的长度
int CircleList_Length(CircleList* list);
//在POS位置插入一个节点
int CircleList_Insert(CircleList* list, CircleListNode* node, int pos);
//获取POS位置节点的信息
CircleListNode* CircleList_Get(CircleList* list, int pos);
//删除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);
//游标的NEXT域
CircleListNode* CircleList_Next(CircleList* list); #endif
CPP文件:
#include "circleList.h"
#include <iostream> using namespace std; //这个为头链表头
typedef struct _tag_CircleList
{
CircleListNode header;
CircleListNode* slider;
int length;
}tagCircleList; //创建一个循环链表
CircleList* CircleList_Create()
{
tagCircleList* ret = (tagCircleList*)malloc(sizeof(tagCircleList)); //分配内存
if (ret == NULL)
{
return NULL;
} //初始化
ret->header.next = NULL;
ret->length = ;
ret->slider = NULL; return ret;
} //删除一个循环链表
void CircleList_Destroy(CircleList* list)
{
if (list = NULL)
{
return;
}
//释放内存
free(list);
return;
} //清空一个循环链表
void CircleList_Clear(CircleList* list)
{
tagCircleList* sList = NULL;
sList = (tagCircleList*)list;
if (sList == NULL)
{
return ;
}
//重置为初始化状态
sList->header.next = NULL;
sList->length = ;
sList->slider = NULL;
return;
} //返回链表的长度
int CircleList_Length(CircleList* list)
{
tagCircleList* sList = NULL;
sList = (tagCircleList*)list;
int ret = -;
//异常处理
if (list == NULL)
{
return ret;
} return sList->length;
} //在POS位置插入一个节点
int CircleList_Insert(CircleList* list, CircleListNode* node, int pos)
{
tagCircleList* sList = NULL;
sList = (tagCircleList*)list;
int ret = -;
//异常处理
if(list == NULL || node == NULL || pos<)
{
return ret;
}
//临时变量Current
CircleListNode* Current = (CircleListNode*)sList; for(int i = ; (i < pos) && (Current->next != NULL); i++)
{
Current = Current->next;
} node->next = Current->next;
Current->next = node; //当长度为0时 游标指向node
if (sList->length == )
{
sList->slider = node;
} sList->length++;
//如果current 依旧指向链表头 证明没跳走 是从0开始插入的 需要头插法
if (Current == (CircleListNode*)sList)
{
//定义一个辅助last 变量来获取尾部节点的信息
CircleListNode* last = (CircleListNode*)CircleList_Get(sList, sList->length - );
//将尾部节点的NEXT域存为当前节点(头节点)
last->next = Current->next;
}
return ;
} //获取POS位置节点的信息
CircleListNode* CircleList_Get(CircleList* list, int pos)
{ tagCircleList* sList = (tagCircleList*)list;
CircleListNode* ret = NULL;
int i = ;
if (list == NULL || pos < )
{
return NULL;
}
CircleListNode* Current = (CircleListNode*)sList;
for(i = ; i < pos; i++)
{
Current = Current->next;
} ret = Current->next;
return ret;
} //删除POS位置的节点
CircleListNode* CircleList_Delete(CircleList* list, int pos)
{
tagCircleList* sList = (tagCircleList*)list;
CircleListNode* ret = NULL; if ((sList != NULL) && (pos >=) && (sList->length > ))
{
//将Current指向表头
CircleListNode* Current = (CircleListNode*)(&(sList->header));
//辅助节点last 进行头节点的删除使用 存取最后一个元素
CircleListNode* last = NULL; for(int i = ; i < pos; i++)
{
Current = Current->next;
}
//删除头结点
if ( Current == (CircleListNode*)sList)
{
last = (CircleListNode*)CircleList_Get(sList, sList->length - );
}
//要删除的元素
ret = Current->next;
Current->next = ret->next;
sList->length--; //判断链表非空
if( last != NULL)
{
//sList->header.next = ret->next;
Current->next = ret->next;
last->next = ret->next;
}
//若删除的元素为游标所指的元素
if(sList->slider = ret)
{
sList->slider = ret->next;
}
//若删除元素后 链表长度为0 做处理
if (sList->length == )
{
sList->header.next = NULL;
sList->slider = NULL;
}
}
return ret;
} ////与游标相关的函数
//删除游标所指的位置节点
CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node)
{
tagCircleList* sList = (tagCircleList*)list;
CircleListNode* ret = NULL;
int i = ; if (sList != NULL)
{
CircleListNode* Current = (CircleListNode*)sList;
//循环查找node 在链表中的位置
for (i = ; i < sList->length; i++)
{
if (Current->next == node)
{
ret = Current->next;
break;
} Current = Current->next;
}
//找到了 使用CircleList_Delete 删除
if(ret != NULL)
{
CircleList_Delete(list, i);
} } return ret;
} //重置游标位置
CircleListNode* CircleList_Reset(CircleList* list)
{
tagCircleList* sList = (tagCircleList*)list;
CircleListNode* ret = NULL;
//如果不为空
if (sList != NULL)
{
sList->slider = sList->header.next;
ret = sList->slider;
} return ret;
} //当前游标位置
CircleListNode* CircleList_Current(CircleList* list)
{
tagCircleList* sList = (tagCircleList*)list;
CircleListNode* ret = NULL;
//如果不为空
if (sList != NULL)
{
ret = sList->slider;
} return ret;
} //把游标位置返回,游标下移
CircleListNode* CircleList_Next(CircleList* list)
{
tagCircleList* sList = (tagCircleList*)list;
CircleListNode* ret = NULL;
//如果不为空
if((sList != NULL) && (sList->slider != NULL))
{
ret = sList->slider;
sList->slider = ret->next;
} return ret;
}
测试函数:
#include "circleList.h"
#include <iostream> using namespace std; typedef struct _Temp_Test
{
CircleListNode node;
int temp;
char temp2;
}TempTast; int main()
{
CircleList* circlelist = NULL; circlelist = CircleList_Create();
//异常处理
if (circlelist == NULL)
{
cout << "Create Err " << endl;
return -;
} TempTast t1, t2, t3, t4, t5;
t1.temp = ;
t2.temp = ;
t3.temp = ;
t4.temp = ;
t5.temp = ;
//插入元素
CircleList_Insert(circlelist, (CircleListNode*)(&t1), );
CircleList_Insert(circlelist, (CircleListNode*)(&t2), );
CircleList_Insert(circlelist, (CircleListNode*)(&t3), );
CircleList_Insert(circlelist, (CircleListNode*)(&t4), );
CircleList_Insert(circlelist, (CircleListNode*)(&t5), );
//测试功能
cout << "Length: " << CircleList_Length(circlelist) << endl;
//遍历两次
cout << "遍历两次:" << endl;
for(int i = ; i < *CircleList_Length(circlelist); i++)
{
cout <<"Node:" << ((TempTast*)CircleList_Get(circlelist, i))->temp << endl;
}
cout << endl;
//删除第一个节点
cout <<"Node:" << ((TempTast*)CircleList_Delete(circlelist, ))->temp << endl;
//清空
CircleList_Clear(circlelist);
cout << "After Clear Length: " << CircleList_Length(circlelist) << endl; //插入元素
CircleList_Insert(circlelist, (CircleListNode*)(&t1), );
CircleList_Insert(circlelist, (CircleListNode*)(&t2), );
CircleList_Insert(circlelist, (CircleListNode*)(&t3), );
CircleList_Insert(circlelist, (CircleListNode*)(&t4), );
CircleList_Insert(circlelist, (CircleListNode*)(&t5), );
//删除指定元素
cout << "Delete Node :" << ((TempTast*)CircleList_DeleteNode(circlelist, (CircleListNode*)(&t1)))->temp << endl;
//显示游标当前位置
cout << "Silder Now :" << ((TempTast*)CircleList_Current(circlelist))->temp << endl;
//移动后
CircleList_Next(circlelist);
cout << "Silder After Next :" << ((TempTast*)CircleList_Current(circlelist))->temp << endl;
//重置后
CircleList_Reset(circlelist);
cout << "Silder After Reset :" << ((TempTast*)CircleList_Current(circlelist))->temp << endl;
cout << endl;
//销毁
CircleList_Destroy(circlelist);
cout << "circle has been Destroied" << endl;
system("pause");
return ;
}
循环链表的C风格实现(单向)的更多相关文章
- python中的单向循环链表实现
引子 所谓单向循环链表,不过是在单向链表的基础上,如响尾蛇般将其首尾相连,也因此有诸多类似之处与务必留心之点.尤其是可能涉及到头尾节点的操作,不可疏忽. 对于诸多操所必须的遍历,这时的条件是什么?又应 ...
- 复习下C 链表操作(单向循环链表、查找循环节点)
循环链表 稍复杂点. 肯能会有0 或 6 字型的单向循环链表. 接下来创建 单向循环链表 并 查找单向循环链表中的循环节点. 这里已6字型单向循环链表为例. //创建 循环链表 Student * ...
- 03-java实现循环链表
03java实现循环链表 本人git https://github.com/bigeyes-debug/Algorithm 一丶单向循环链表 就是为尾节点指向头结点 二丶单向循环链表的接口设计 比较单 ...
- Java集合源码分析(三)LinkedList
LinkedList简介 LinkedList是基于双向循环链表(从源码中可以很容易看出)实现的,除了可以当做链表来操作外,它还可以当做栈.队列和双端队列来使用. LinkedList同样是非线程安全 ...
- 数据结构Java实现04----循环链表、仿真链表
单向循环链表 双向循环链表 仿真链表 一.单向循环链表: 1.概念: 单向循环链表是单链表的另一种形式,其结构特点是链表中最后一个结点的指针不再是结束标记,而是指向整个链表的第一个结点,从而使单链表形 ...
- 基本数据结构:链表(list)
copy from:http://www.cppblog.com/cxiaojia/archive/2012/07/31/185760.html 基本数据结构:链表(list) 谈到链表之前,先说一下 ...
- 用Python实现的数据结构与算法:链表
一.概述 链表(linked list)是一组数据项的集合,其中每个数据项都是一个节点的一部分,每个节点还包含指向下一个节点的链接(参考 <算法:C语言实现>). 根据结构的不同,链表可以 ...
- Python实现的数据结构与算法之链表详解
一.概述 链表(linked list)是一组数据项的集合,其中每个数据项都是一个节点的一部分,每个节点还包含指向下一个节点的链接.根据结构的不同,链表可以分为单向链表.单向循环链表.双向链表.双向循 ...
- 基于visual Studio2013解决算法导论之021单向循环链表
题目 单向循环链表的操作 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <time.h> ...
随机推荐
- 牛客寒假6-B.煤气灶
链接:https://ac.nowcoder.com/acm/contest/332/B 题意: 小j开始打工,准备赚钱买煤气灶. 第一天,小j的工资为n元,之后每天他的工资都比前一天多d元. 已知煤 ...
- A.出题人的RP值
链接:https://ac.nowcoder.com/acm/contest/358/A 题意: 众所周知,每个人都有自己的rp值(是个非负实数),膜别人可以从别人身上吸取rp值. 然而当你膜别人时, ...
- python入门之数据类型之字符串
str方法 name.capitalize() 将name的首字母大写 name.center(20,'*') 将name居中,长度变为20,其余用*填充 name.count('chy') 返回na ...
- JTable运行的时候抛出NullPointerException的问题
在一个需要动态更新JTable的程序中,为了实现动态刷修数据.在主线程之外开了个新线程来进行算法的执行还有数值计算,然后最后调用 jTable.updateUi(); 的方法. 然后图形界面上是一点问 ...
- jdk1.8源码包下载并导入到开发环境下助推高质量代码(Eclipse、MyEclipse和Scala IDEA for Eclipse皆适用)(图文详解)
不多说,直接上干货! jdk1.8 源码, Linux的同学可以用的上. 由于源码JDK是前版本的超集, 所以1.4, 1.5, 1.6, 1.7都可以用的上. 其实大家安装的jdk路径下,这 ...
- css3のtext-shadow
text-shadow,让我们大家一起来学习一下吧. 语法: text-shadow:none | <shadow> [ , <shadow> ]* <shadow> ...
- 理解C#系列 / 前言
前言 索引 写什么? 为什么写? 怎么写? 写什么? 写和C#编程相关的知识. 写知识的定义,附加对知识的理解. 写知识的作用,使用的场景,使用的条件. 写知识的本质,技术的结构,工作的原理. 写知识 ...
- Android 检查内存溢出
工具网址:https://github.com/square/leakcanary 中文版说明地址:http://www.liaohuqiu.net/cn/posts/leak-canary-read ...
- uvm_monitor——借我一双慧眼
monitor 用来捕获(监视)和检查总线的信号是否满足预期的要求.所有的user_monitor 继承自uvm_monitor,uvm_monitor继承自uvm_component,从源代码来看里 ...
- 【R语言进行数据挖掘】决策树和随机森林
1.使用包party建立决策树 这一节学习使用包party里面的函数ctree()为数据集iris建立一个决策树.属性Sepal.Length(萼片长度).Sepal.Width(萼片宽度).Peta ...