循环链表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 ...
随机推荐
- js截取字符串相关的知识点
截取字符串中的数字 1.使用parseInt() var str ="4500元"; var num = parseInt(str); console.log(num);//450 ...
- Django框架——基础教程(总)
1. Django简介 Python下有许多款不同的 Web 框架.Django是重量级选手中最有代表性的一位.许多成功的网站和APP都基于Django. Django是一个开放源代码的Web应用框架 ...
- Linux配置nginux
安装依赖 yum install gcc yum install pcre-devel yum install zlib zlib-devel yum install openssl openssl- ...
- 深入理解python元类
类也是对象 在理解元类之前,你需要先掌握Python中的类.Python 中的类概念借鉴 Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.当然在 P ...
- 并发编程系列:Java线程池的使用方式,核心运行原理、以及注意事项
并发编程系列: 高并发编程系列:4种常用Java线程锁的特点,性能比较.使用场景 线程池的缘由 java中为了提高并发度,可以使用多线程共同执行,但是如果有大量线程短时间之内被创建和销毁,会占用大量的 ...
- 为什么angular library的build不能将assets静态资源打包进去(转)
Versions Angular CLI: 6.0.7 Node: 9.3.0 OS: darwin x64 Angular: 6.0.3 ... animations, common, compil ...
- centos 7 Network 脚本
#!/bin/sh #主动启动网卡 interface=$() ifup $interface #获取当前网络信息 default_route=$(ip route show) default_int ...
- Dubbo 03 Restful风格的API
目录 Dubbo03 restful风格的API 根路径 协议 版本 用HTTP协议里的动词来实现资源的增删改查 用例 swagger(丝袜哥) OpenAPI 资源 编写API文档 整合Spring ...
- 北美CS求学找工指南
这篇文章主要谈谈来美求学工作这一路的点点滴滴,因为之前留言中不少同学对这方面内容比较感兴趣,有些已经在准备,有些还在犹豫,希望本文能对大家有些许帮助.因为来美的途径也有不少,有上学.有投资.有通过国内 ...
- flutter 学习路上碰到的错误问题。
决定还是把碰到的问题进行简单记录吧 19.8.14 错误日志: type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subty ...