Linux-C学习笔记-双向循环链表(支持DEBUG调试)
来源:互联网 发布:液压系统绘图软件 编辑:程序博客网 时间:2024/06/06 17:26
双向循环链表功能强大,本文件是双向循环链表的实现函数,包括链表创建,删除,清空,获取链表长度, 获取链表结点,删除链表结点,适用于任意类型的数据结点,链表逆序操作在双向循环链表中的意义和作用不大,故不用实现,使用时传入数据结点指针,及其他参数即可
本代码支持DEBUG调试
/********************************************************************************************************************************************
file DbCircleList.h
#ifndef _DBCIRCLELIST_H_ #define _DBCIRCLELIST_H_ typedef void DbCircleList; typedef void DbCircleListNode; extern DbCircleList* DbCircleList_Create(); extern void DbCircleList_Destroy(DbCircleList* list); extern void DbCircleList_Clear(DbCircleList* list); extern int DbCircleList_Length(DbCircleList* list); extern int DbCircleList_Insert(DbCircleList* list, DbCircleListNode* node, int pos); extern DbCircleListNode* DbCircleList_Get(DbCircleList* list, int pos); extern DbCircleListNode* DbCircleList_Delete(DbCircleList* list, int pos); extern void DbCircleList_Reverse(DbCircleList* list); #endif
/********************************************************************************************************************************************
file DbCircleList.c
/*************************************************************************** 文件名 : DbCircleList.c* 文件说明 :本文件是双向循环链表的实现函数,包括链表创建,删除,清空,获取链表长度,* 获取链表结点,删除链表结点,适用于任意类型的数据结点,链表逆序操作在双* 向循环链表中的意义和作用不大,故不用实现,使用时传入数据结点指针,及其* 他参数即可**************************************************************************///库文件包含#include <stdio.h> #include <malloc.h> //本地头文件包含#include "DbCircleList.h"//调试开关#define DEBUG//结构体定义//封装数据结点定义typedef struct _tag_TDbCircleListNode TDbCircleListNode; struct _tag_TDbCircleListNode { unsigned int addr;//数据结点地址保存区 TDbCircleListNode* prior; //链表指针TDbCircleListNode* next; //链表指针};//封装链表头结点typedef struct _tag_TDbCircleList { int length;//链表长度 TDbCircleListNode* header;//链表头指针}TDbCircleList; //函数实现/********************************************************************************** 函数原型:DbCircleList* DbCircleList_Create()* 函数说明:创建循环链表* 参数说明:输入参数:无* 输出参数:无* 返回值:DbCircleList* 循环链表指针*********************************************************************************/DbCircleList* DbCircleList_Create(){//申请头结点空间 TDbCircleList* ret = (TDbCircleList*)malloc(sizeof(TDbCircleList)); #ifdef DEBUGprintf("DbCircleList_Create...");#endif if(ret != NULL) { ret->length = 0;//循环链表长度初始化 ret->header = NULL;//循环链表头结点指针初始化 }#ifdef DEBUG(ret == NULL) ? printf(" Failed.\n") : printf(" Successful.\n");#endif return (DbCircleList*)ret;//返回循环链表指针} /********************************************************************************** 函数原型:void DbCircleList_Destroy(DbCircleList* list)* 函数说明:删除循环链表* 参数说明:输入参数:DbCircleList* list 循环链表指针* 输出参数:无* 返回值:无*********************************************************************************/void DbCircleList_Destroy(DbCircleList* list) {#ifdef DEBUGprintf("DbCircleList_Destroy...\n");#endif DbCircleList_Clear(list);//清空循环链表 free((TDbCircleList*)list);//释放头结点空间 list = NULL;//清空链表指针#ifdef DEBUGprintf("DbCircleList_Destroy...Complete.\n");#endif} /********************************************************************************** 函数原型:void DbCircleList_Clear(DbCircleList* list)* 函数说明:循环链表清空* 参数说明:输入参数:DbCircleList* list 循环链表指针* 输出参数:无* 返回值:无*********************************************************************************/void DbCircleList_Clear(DbCircleList* list) { TDbCircleList* sList = (TDbCircleList*)list;#ifdef DEBUGprintf("DbCircleList_Clear...\n");#endif//链表指针非空且链表有数据结点才可清空 if(sList != NULL && sList->header != NULL) {//从编号为0(编号从0开始)的结点开始删除 while(sList->header != sList->header->next) {TDbCircleListNode* pNode = sList->header;sList->header->prior->next = pNode->next;sList->header->next->prior = pNode->prior;sList->header = sList->header->next;#ifdef DEBUGprintf("Clear Node %d .\n", pNode->addr);#endif free(pNode); sList->length--; }//删除剩余的编号为0的结点#ifdef DEBUGprintf("Clear Header Node %d .\n", sList->header->addr);#endiffree(sList->header);sList->header = NULL;sList->length--; }#ifdef DEBUGprintf("DbCircleList_Clear...Complete.\n");#endif}/********************************************************************************** 函数原型:int DbCircleList_Length(DbCircleList* list) * 函数说明:获取单链表长度 * 参数说明:输入参数:DbCircleList* list 循环链表指针* 输出参数:无* 返回值:获取失败返回-1* 获取成功返回非负数(单链表当前长度)************************************************************************/ int DbCircleList_Length(DbCircleList* list) {int ret = -1; TDbCircleList* sList = (TDbCircleList*)list; #ifdef DEBUGprintf("DbCircleList_Length...");#endif if(sList != NULL) { ret = sList->length; }#ifdef DEBUG(ret == -1) ? printf(" list is NULL.\n") : printf(" %d\n", ret);#endif return ret; }/********************************************************************************** 函数原型:int DbCircleList_Insert(DbCircleList* list, DbCircleListNode* node, int pos) * 函数说明:向循环链表中插入结点 * 参数说明:输入参数:DbCircleList* list 循环链表指针* DbCircleListNode* node 待插入链表数据地址* int pos 插入位置,从0开始* 输出参数:无* 返回值:获取失败返回假(0)* 获取成功返回真(1)*********************************************************************************/ int DbCircleList_Insert(DbCircleList* list, DbCircleListNode* node, int pos) { TDbCircleList* sList = (TDbCircleList*)list; int ret = (sList != NULL) && (node != NULL); //检查链表#ifdef DEBUGprintf("DbCircleList_Insert...");#endif if(ret) {//申请数据结点空间 TDbCircleListNode* pNew = (TDbCircleListNode*)malloc(sizeof(TDbCircleListNode)); if(pNew != NULL) {//保存数据 pNew->addr = (unsigned int)node;#ifdef DEBUGprintf("Insert Node data %d ", pNew->addr);#endif//链表为空时默认插入0号位置if(sList->header == NULL){pNew->next = pNew;pNew->prior = pNew;sList->header = pNew;sList->length++;#ifdef DEBUGprintf(" In Header Node\n");#endif}else{//链表不为空时int index = (pos >= 0) ? (1) : (-1);int halfLength = (sList->length + 1) / 2;//修正插入位置pos = index * pos;pos = pos % (sList->length + 1);pos = (pos < halfLength) ? (pos) : (-(sList->length - pos));pos = index * pos;if(pos == 0){//插入0位置pNew->next = sList->header;sList->header->prior->next = pNew;pNew->prior = sList->header->prior;sList->header->prior = pNew;sList->header = pNew;}else{//插入其他位置:将新结点插入到pos编号结点的前面//寻找插入位置TDbCircleListNode* current = sList->header;if(pos > 0){for(index = 0; index < pos; index ++){current = current->next;}}else{for(index = -1; index > pos; index --){current = current->prior;}}//插入数据节点到pos编号结点的前面pNew->next = current->prior->next;current->prior->next = pNew;pNew->prior = current->prior;current->prior = pNew;}sList->length++;#ifdef DEBUGprintf(" In %d Node\n", pos);#endif} } else { ret = 0; } }#ifdef DEBUGif(ret == 0)printf(" Failed.\n");#endif return ret; } /********************************************************************************** 函数原型:DbCircleListNode* DbCircleList_Get(DbCircleList* list, int pos)* 函数说明:获取链表中编号为pos的数据* 参数说明:输入参数:DbCircleList* list 循环链表指针* int pos 获取编号,从0开始* 输出参数:无* 返回值:DbCircleListNode* 链表数据地址,为空表示获取失败*********************************************************************************/ DbCircleListNode* DbCircleList_Get(DbCircleList* list, int pos) { TDbCircleList* sList = (TDbCircleList*)list; DbCircleListNode* ret = NULL; #ifdef DEBUGprintf("DbCircleList_Get...");#endif//判断链表是否合法,判断获取位置是否合法 if( (sList != NULL) && (0 <= pos) ) {int index = (pos >= 0) ? (1) : (-1);int halfLength = (sList->length) / 2;TDbCircleListNode* current = sList->header;//修正获取位置编号pos = index * pos;pos = pos % (sList->length);pos = (pos < halfLength) ? (pos) : (-(sList->length - pos));pos = index * pos;//查找获取位置if(pos >= 0){for(index = 0; index < pos; index ++){current = current->next;}}else{for(index = -1; index > pos; index --){current = current->prior;}}#ifdef DEBUGprintf(" From %d Node", pos);#endif ret = (DbCircleListNode*)(current->addr); }#ifdef DEBUG(ret == NULL) ? printf(" Failed.\n") : printf(" %d .\n", (int)ret);#endif return ret; } /********************************************************************************** 函数原型:DbCircleListNode* DbCircleList_Delete(DbCircleList* list, int pos) * 函数说明:删除链表中编号为pos的数据,并将其返回* 参数说明:输入参数:DbCircleList* list 循环链表指针* int pos 获取编号,从0开始* 输出参数:无* 返回值:DbCircleListNode* 链表数据地址,为空表示删除失败*********************************************************************************/ DbCircleListNode* DbCircleList_Delete(DbCircleList* list, int pos) { TDbCircleList* sList = (TDbCircleList*)list; DbCircleListNode* ret = NULL; #ifdef DEBUGprintf("DbCircleList_Delete...");#endif//判断链表是否合法,判断获取位置是否合法 if( (sList != NULL) && (0 <= pos) ) {int index = (pos >= 0) ? (1) : (-1);int halfLength = (sList->length) / 2;TDbCircleListNode* current = sList->header;//修正删除位置编号pos = index * pos;pos = pos % (sList->length);pos = (pos < halfLength) ? (pos) : (-(sList->length - pos));pos = index * pos;//查找删除位置if(pos >= 0){for(index = 0; index < pos; index ++){current = current->next;}}else{for(index = -1; index > pos; index --){current = current->prior;}}//保存删除数据 ret = (DbCircleListNode*)(current->addr);#ifdef DEBUGprintf(" From %d Node", pos);#endif //若删除的是编号为0的结点,先修改头指针if(pos == 0){sList->header = sList->header->next;}//删除结点current->prior->next = current->next;current->next->prior = current->prior;free(current);sList->length--;//若删除完后,链表长度为0,复位链表if(sList->length == 0){sList->header = NULL;} }#ifdef DEBUG(ret == NULL) ? printf(" Failed.\n") : printf(" %d .\n", (int)ret);#endif return ret;}
/********************************************************************************************************************************************
file main.c
#include <stdio.h>#include <stdlib.h>#include "DbCircleList.h"#define TEST_NUM 10char Test_Data[10] = {'0','1','2','3','4','5','6','7','8','9'};int main(int argc, char *argv[]){int index = 0;DbCircleList* list = DbCircleList_Create();printf(" Length Before Insert = %d\n", DbCircleList_Length(list));for(index = 0; index < TEST_NUM - 2; index ++){DbCircleList_Insert(list, Test_Data+index, 0);}printf(" Length After Insert and Before Clear = %d\n", DbCircleList_Length(list));DbCircleList_Clear(list);printf(" Length After Clear and Before Insert again = %d\n", DbCircleList_Length(list));for(index = 0; index < TEST_NUM; index ++){DbCircleList_Insert(list, Test_Data+index, -7);}printf(" Length After Insert again and Before Delete = %d\n", DbCircleList_Length(list));for(index = 0; index < DbCircleList_Length(list); index ++){printf("%c\n", *(char *)DbCircleList_Get(list, index));}printf("Delete:\n");for(index = 0; index < TEST_NUM/2; index ++){printf("%c\n", *(char *)DbCircleList_Delete(list, 0));}printf("After Delete:\n");for(index = 0; index < DbCircleList_Length(list); index ++){printf("%c\n", *(char *)DbCircleList_Get(list, index));}printf("Destroy:\n");DbCircleList_Destroy(list);printf("Test Complete.\nPlease Input a char to Quit :");Test_Data[0] = getchar();return 0;}
- Linux-C学习笔记-双向循环链表(支持DEBUG调试)
- Linux-C学习笔记-循环链表
- 双向循环链表list(C++)
- C——(单向、单向循环、双向、双向循环)链表学习总结
- Linux双向循环链表(上)
- linux 双向循环链表(下)
- C双向链表学习笔记
- linux中C语言实现双向循环链表
- Linux内核中的双向循环链表学习
- 数据结构学习笔记 --- 线性表 (双向链表、循环链表)
- 数据结构学习笔记 --- 线性表 (双向链表、循环链表)
- 数据结构学习笔记 --- 线性表 (双向链表、循环链表)
- 双向循环链表的实现(C)
- 队列实现 (双向循环链表 C++)
- 双向循环链表基本操作(C语言)
- 双向循环链表程序(C语言版)
- C语言实现双向循环链表
- C语言中的双向循环链表
- Java调用Google Analytics API实现网站统计
- root 权限--待续
- eclipse离线安装插件
- JAVA中字符串和整型之间的转换
- cocos2d-x2.2 新建项目
- Linux-C学习笔记-双向循环链表(支持DEBUG调试)
- 级联查询在javascript与struts2中区别
- Expect 教程中文版
- object-c runloop
- java io 常用方法
- 深入分析 Linux 内核链表
- IOS推送证书的制作
- windows下安装ruby on rails 环境搭建·
- LeetCode 之 Palindrome Number