循环链表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 ...
随机推荐
- NIO、BIO、AIO
BIO(同步阻塞):Socket编程就是 BIO ,操作时会阻塞线程,并发处理能力低 .阻塞的原因在于:操作系统允许的线程数量是有限的,多个socket申请与服务端建立连接时,服务端不能提供相应数量的 ...
- CSS---解决文本溢出,换行
当我们设置我的的div,或者其它文本框固定宽度之后,文本内容过多就会出文本溢出(显示在区域外面,不换行的情况). 这时我们可以使用Css中的几个属于来解.有以下的三个属于可以解决问题: 1,word- ...
- 精通shell编程--最后的总结
不得不说shell语法是丑陋的,操作是简单高效的,最后一次学习总结shell shell总结 字符串删除与替换等常见操作 ## 字符串长度 a=1234 echo "${#a}" ...
- 配置maven的国内镜像
pom.xml文件出现错误标记,一般是相关的maven资源没有下载完整. 1,配置maven的国内镜像,保证能够顺利下载maven中配置的资源. 在maven的配置文件 settings.xml ...
- 基于nginx与Tomcat实现负载均衡
server1:192.168.200.113(nginx服务端) server2:192.168.200.111(Tomcat服务端) server1中nginx的配置文件 nginx.conf h ...
- 利用shell脚本做一个用户登录系统
效果图如下: #!/bin/bash# while truedocat << EOF//======================\\\\| 用户登录系统 |-------------- ...
- Linux搭建局域网yum源和后期在yum源中更新rpm包方法
在内网中搭建自己的yum源,可以方便在内网中使用,下面简单介绍搭建局域网yum源的方法和后期更新yum源rpm包的方法. 一.搭建局域网yum源 1.需要在局域网访问,首先需要一个web服务器,比如a ...
- 关于Java中线程取值并返回的方法
如何让一个线程不断跑起来,并且在取到值的时候能返回值而线程能继续跑呢? 我们都知道可以用Callable接口获得线程的返回值,或者触发事件监听来操作返回值,下面我将介绍另一种方法. public ab ...
- Zookeeper客户端使用(使用Curator)
Zookeeper客户端(使用Curator) 三.使用curator客户端 在pom.xml中加入依赖 <dependency> <groupId>org.apache.cu ...
- hive不分区增量更新
insert overwrite table ods.zeg_so select *,case when zsm.id is not null then cast(current_timestamp ...