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;}

原创粉丝点击