循环链表C语言实现
按照单链表的设计,稍加改动。和单向链表不一样的地方,头节点不指向NULL,而是指向自己head
循环链表的判满 1)判断next是不是头结点,2)判断size
/*
* CycleLinkList.h
*
* Created on: 2019年7月24日
* Author: Administrator
*/
#ifndef SRC_CYCLELINKLIST_H_
#define SRC_CYCLELINKLIST_H_
#define CIRCLELINKLIST_TRUE 1
#define CIRCLELINKLIST_FALSE 0
/**
* 1、循环链表,带头节点,初始化的时候,和单向链表不一样的地方,头节点不指向NULL,而是指向自己head
* 2、循环链表的判满 1)判断next是不是头结点,2)判断size
* */
//链表的小节点
typedef struct CIRCLELINKNODE {
struct CIRCLELINKNODE *next;
}CircleLinkNode;
//结构体
typedef struct CIRCLELINKLIST {
CircleLinkNode head;
int size;
}CircleLinkList;
//比较回调
typedef int(*COMPARENODE)(CircleLinkNode *, CircleLinkNode *);
typedef void(*PRINTNODE)(CircleLinkNode *);
//API
//创建一个循环链表
CircleLinkList *Init_CircleLinkList();
//插入
void Insert_CircleLinkList(CircleLinkList *clist, int pos, CircleLinkNode *data);
//获取第一个元素
CircleLinkNode *Front_CircleLinkList(CircleLinkList *clist);
//根据位置删除
void RemoveByPos_CircleLinkList(CircleLinkList *clist, int pos);
//根据值删除
void RemoveByValue_CircleLinkList(CircleLinkList *clist, CircleLinkNode *data, COMPARENODE compare);
//获得链表的长度
int Size_CircleLinkList(CircleLinkList *clist);
//判断是否为空
int IsEmpty_CircleLinkList(CircleLinkList *clist);
//查找
int Find_CircleLinkList(CircleLinkList *clist, CircleLinkNode *data, COMPARENODE compare);
//打印
void Print_CircleLinkList(CircleLinkList *clist, PRINTNODE print);
//释放内存
void FreeSpace_CircleLinkList(CircleLinkList *clist);
#endif /* SRC_CYCLELINKLIST_H_ */
/*
* CylceLinkList.c
*
* Created on: 2019年7月24日
* Author: Administrator
*/
#include "CycleLinkList.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//创建一个循环链表
CircleLinkList *Init_CircleLinkList() {
CircleLinkList *clist = (CircleLinkList *)malloc(sizeof(CircleLinkNode));
clist->head.next = &(clist->head);
clist->size = 0;
return clist;
}
//插入
void Insert_CircleLinkList(CircleLinkList *clist, int pos, CircleLinkNode *data) {
if(clist == NULL){
return;
}
if(data == NULL){
return;
}
if(pos < 0 || pos > clist->size){
pos = clist->size;
}
//根据位置查找节点
//操作指针的时候一定要引入一个指针变量,不然很可能改变指针
CircleLinkNode *pCurrent = &(clist->head);
for(int i = 0; i < pos; i++){
pCurrent = pCurrent->next;
}
data->next = pCurrent->next;
pCurrent->next = data;
clist->size++;
}
//获取第一个元素
CircleLinkNode *Front_CircleLinkList(CircleLinkList *clist) {
return clist->head.next;
}
//根据位置删除
void RemoveByPos_CircleLinkList(CircleLinkList *clist, int pos) {
if(clist == NULL){
return;
}
if(pos < 0 || pos>= clist->size){
return;
}
//根据pos 找节点
//辅助指针变量
CircleLinkNode *pCurrent = &(clist->head);
for(int i = 0; i < pos; i++){
pCurrent = pCurrent->next;
}
//缓存当前节点的下一个节点
CircleLinkNode *pNext = pCurrent->next;
pCurrent->next = pNext->next;
clist->size--;
}
//根据值删除
void RemoveByValue_CircleLinkList(CircleLinkList *clist, CircleLinkNode *data, COMPARENODE compare) {
if(clist == NULL){
return;
}
if(data == NULL){
return;
}
//这是循环链表
CircleLinkNode *pPrev = &(clist->head);//找到相等打的元素值时,存储要删除的元素的前驱节点
CircleLinkNode *pCurrent = clist->head.next;//用来记录 要删除的元素的结点
for(int i = 0; i < clist->size; i++){
if(compare(pCurrent, data) == CIRCLELINKLIST_TRUE){//找点操作
pPrev->next = pCurrent->next;//删除操作
break;
}
pPrev = pCurrent;//比较指针后移
pCurrent = pCurrent->next;//游标指针后移
}
free(pCurrent);
clist->size--;
}
//获得链表的长度
int Size_CircleLinkList(CircleLinkList *clist) {
return clist->size;
}
//判断是否为空
int IsEmpty_CircleLinkList(CircleLinkList *clist) {
if(clist->size == 0){
return CIRCLELINKLIST_TRUE;
}
return CIRCLELINKLIST_FALSE;
}
//查找
int Find_CircleLinkList(CircleLinkList *clist, CircleLinkNode *data, COMPARENODE compare) {
if(clist == NULL){
return -1;
}
if(data == NULL){
return -1;
}
CircleLinkNode *pCurrent = clist->head.next;
int flag = -1;
for(int i = 0; i < clist->size; i++){
if(compare(pCurrent, data) == CIRCLELINKLIST_TRUE){
flag = i;
break;
}
pCurrent = pCurrent->next;
}
return flag;
}
//打印
void Print_CircleLinkList(CircleLinkList *clist, PRINTNODE print) {
if(clist == NULL){
return;
}
//辅助指针变量
CircleLinkNode *pCurrent = clist->head.next;
for(int i = 0; i < clist->size; i++){
if(pCurrent == pCurrent->next){
pCurrent = pCurrent->next;
}
print(pCurrent);
pCurrent = pCurrent->next;
}
}
//释放内存
void FreeSpace_CircleLinkList(CircleLinkList *clist) {
if(clist == NULL){
return;
}
free(clist);
}
/*
* main.c
*
* Created on: 2019年7月24日
* Author: Administrator
*/
#include "CycleLinkList.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct PERSON{
CircleLinkNode node;
char name[64];
int age;
int score;
}Person;
void MyPrint(CircleLinkNode *data){
Person *p = (Person *)data;
printf("name: %s , age: %d, score: %d \n", p->name, p->age, p->score);
}
int MyCompare(CircleLinkNode *data1, CircleLinkNode *data2){
Person *p1 = (Person *)data1;
Person *p2 = (Person *)data2;
if(strcmp(p1->name, p2->name) == 0 && p1->age == p2->age && p1->score == p2->score){
return CIRCLELINKLIST_TRUE;
}
}
int main(){
printf("循环链表 \n");
//创建循环链表
CircleLinkList *clist = Init_CircleLinkList();
//创建数据
Person p1, p2, p3, p4, p5;
strcpy(p1.name, "Jarvis");
strcpy(p2.name, "Marvis");
strcpy(p3.name, "Harvis");
strcpy(p4.name, "Larvis");
strcpy(p5.name, "Karvis");
p1.age = 21;
p2.age = 22;
p3.age = 23;
p4.age = 24;
p5.age = 25;
p1.score = 91;
p2.score = 92;
p3.score = 93;
p4.score = 94;
p5.score = 95;
Insert_CircleLinkList(clist, 0, (CircleLinkNode *)&p1);
Insert_CircleLinkList(clist, 1, (CircleLinkNode *)&p2);
Insert_CircleLinkList(clist, 2, (CircleLinkNode *)&p3);
Insert_CircleLinkList(clist, 3, (CircleLinkNode *)&p4);
Insert_CircleLinkList(clist, 4, (CircleLinkNode *)&p5);
//打印
Print_CircleLinkList(clist, MyPrint);
//删除
Person pDel;
strcpy(pDel.name, "Marvis");
pDel.age = 22;
pDel.score = 92;
RemoveByValue_CircleLinkList(clist, (CircleLinkNode *)&pDel, MyCompare);
//打印
printf("删除后打印 \n");
Print_CircleLinkList(clist, MyPrint);
//释放内存
FreeSpace_CircleLinkList(clist);
system("pause");
return 0;
}
循环链表
name: Jarvis , age: 21, score: 91
name: Marvis , age: 22, score: 92
name: Harvis , age: 23, score: 93
name: Larvis , age: 24, score: 94
name: Karvis , age: 25, score: 95
删除后打印
name: Jarvis , age: 21, score: 91
name: Harvis , age: 23, score: 93
name: Larvis , age: 24, score: 94
name: Karvis , age: 25, score: 95
循环链表C语言实现的更多相关文章
- 一种神奇的双向循环链表C语言实现
最近在看ucore操作系统的实验指导.里面提要一个双向循环链表的数据结构,挺有意思的. 其实这个数据结构本身并不复杂.在普通链表的基础上加一个前向指针,我们就得到了双向链表,再把头尾节点连起来就是双向 ...
- 单向循环链表C语言实现
我们都知道,单向链表最后指向为NULL,也就是为空,那单向循环链表就是不指向为NULL了,指向头节点,所以下面这个程序运行结果就是,你将会看到遍历链表的时候就是一个死循环,因为它不指向为NULL,也是 ...
- 带头结点的双向循环链表----------C语言
/***************************************************** Author:Simon_Kly Version:0.1 Date: 20170520 D ...
- C语言通用双向循环链表操作函数集
说明 相比Linux内核链表宿主结构可有多个链表结构的优点,本函数集侧重封装性和易用性,而灵活性和效率有所降低. 可基于该函数集方便地构造栈或队列集. 本函数集暂未考虑并发保护. 一 ...
- 双向循环链表(C语言描述)(四)
下面以一个电子英汉词典程序(以下简称电子词典)为例,应用双向循环链表.分离数据结构,可以使逻辑代码独立于数据结构操作代码,程序结构更清晰,代码更简洁:电子词典的增.删.查.改操作分别对应于链表的插入. ...
- 1.Go语言copy函数、sort排序、双向链表、list操作和双向循环链表
1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 package main import "fmt" func main() ...
- C语言编程丨循环链表实现约瑟夫环!真可谓无所不能的C!
循环链表 把链表的两头连接,使其成为了一个环状链表,通常称为循环链表. 和它名字的表意一样,只需要将表中最后一个结点的指针指向头结点,链表就能成环儿,下图所示. 需要注意的是,虽然循环链表成环 ...
- 【C语言教程】“双向循环链表”学习总结和C语言代码实现!
双向循环链表 定义 双向循环链表和它名字的表意一样,就是把双向链表的两头连接,使其成为了一个环状链表.只需要将表中最后一个节点的next指针指向头节点,头节点的prior指针指向尾节点,链表就能成环儿 ...
- c语言编程之双向循环链表
双向循环链表就是形成两个环,注意每个环的首尾相连基本就可以了. 程序中采用尾插法进行添加节点. #include<stdio.h> #include<stdlib.h> #de ...
随机推荐
- C++ 对象构造顺序、构析函数、临时对象。
对象的构造顺序: 1.对于局部对象,构造顺序是根据程序执行流进行构造,从上到下. #include <stdio.h> class Test { int mi; public: Test( ...
- cassandra查询效率探讨
cassandra目前提倡的建表与查询方式为CQL方式,传统的cassandra-cli相关的api由于性能问题将逐步淘汰,而cassandra-cli也将在2.2版本之后被淘汰. 在CQL中,可以利 ...
- Python名称空间与作用域
什么是名称空间? 比如下图的长方形代表内存,在这个内存里我要设置一个变量100,那么这个变量得有个门牌号,就叫他a吧,但其实变量不是这么存储的,他其实的存储方式是这样的,他会有一个名称空间,这个名称空 ...
- 小程序UI设计(3)-符合视觉规范-列表视觉规范
上一篇我们介绍了字体规范,此贴介绍一下在列表中如何组合使用.下图是微信官方的要求 在工具中通过拖拽组件可以制作出一样的效果拖拽一个WViewRow.这个组件是小程序的view,flex-direc ...
- cmd 创建并写入文件
一.建立空文件的几种方法1.cd.>a.txtcd.表示改变当前目录为当前目录,即等于没改变:而且此命令不会有输出.>表示把命令输出写入到文件.后面跟着a.txt,就表示写入到a.txt. ...
- zencart简单设置分类链接不同css样式
includes/templates/模板/sideboxes/tpl_categories.php $content .= '<a class="'.$new_style.'&quo ...
- django 自带认证系统(login,logout,authenticate,login_required)
from django.contrib.auth import login,authenticate,logoutfrom django.contrib.auth.decorators import ...
- Redis集群方案(来自网络)
参考: https://www.zhihu.com/question/21419897 http://www.cnblogs.com/haoxinyue/p/redis.html 为什么集群? 通常, ...
- Mongodb文档查询
MongoDB 查询数据的语法格式如下: db.collection.find(query, projection) query :可选,使用查询操作符指定查询条件 projection :可选,使用 ...
- python ddt及logging(九)
一.安装 ①执行语句: pip install ddt ②在单元测试中DDT用来进行数据驱动,数据与测试代码分离(数据发生变化时,用例可以保持不变),一组数据来执行相同的操作. 一般进行接口测试时,每 ...