循环链表的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> ...
随机推荐
- LIS的简单应用:UVA-437
上一次紫芝详细地介绍了动态规划中的经典问题LIS,今天我们抽出一个类似思想的简单题目进行实践练习. The Tower of Babylon(巴比伦塔) Perhaps you have heard ...
- TDH-hbase shell 常用命令
一.HBASE shell 命令操作;1.建表: create ‘tableName’,'f1','f2'; 注:列簇,裂限定符都要尽量短: 2.插入数据: put 'tableName','RowK ...
- 修改php默认的FastCGI模式为ISAPI模式的方法
一.到www.php.net中下载PHP的ZIP文件包.注意版本要对应. 二.将sapi目录中的:php4isapi.dll复制到c:\php目录中. 三.进入虚拟主机管理平台的"网站管理& ...
- aspx页面调用webapi接口报错:远程服务器返回错误:(500)内部服务器错误
代码在运行到response = (HttpWebResponse)request.GetResponse();就开始报错 原因:可能因为所调用的接口不存在或者接口中存在错误,可用postman测试接 ...
- AJPFX关于Collection接口的总结
###15Collection-List-ArrayList/LinkedList/* * Collection接口中的方法* A:添加功能* boolean add ...
- ES6中新增的字符串方法
实例方法:includes(), startsWith(), endsWith() 传统上,JavaScript 只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中.ES6 又提供 ...
- [Luogu1343]地震逃生 最大流
题目链接:https://www.luogu.org/problem/show?pid=1343 dinic跑最大流. #include<cstdio> #include<cstri ...
- Objective-C Protocols
Objective-C allows you to define protocols, which declare the methods expected to be used for a part ...
- CPU性能的评价
人们通常用benchmark 来衡量CPU的性能,常见的benchmark有dhrystone和coremark. 由于dhrystone 受编译器影响比较大,所以,结果不是很准确,现在大多采用cor ...
- org.springframework.beans.factory.BeanCreationException: Could not autowire
由于我在项目中引用了如下代码,增加了 @Configurationpublic class Connection { public @Bean HttpClientConfig httpClie ...