您的位置:首页 > 理论基础 > 数据结构算法

数据结构(18)双向循环链表

2015-08-11 14:49 711 查看
双向循环链表,也就是在双向链表的基础上加上循环链表的特性,使其首尾相连。最后的next指针指向首元素,而首元素的pre指针指向尾元素。

如图




这里介绍双向链表的常用操作:

l 创建双向链表
l 销毁双向链表
l 清空双向链表
l 获取表长度
l 把node插入pos位置
l 获取pos位置的元素
l 删除pos位置的元素
l 删除表中与node相同的元素(删除第一个匹配成功的)
l 重置游标
l 返回游标所指向的结点
l 游标后移
l 游标前移

代码总分为三个文件:



DLinkCircleList.h : 放置功能函数的声明,以及表的声明,表结点的定义
DLinkCircleList.c : 放置功能函数的定义,以及表的定义
Main.c : 主函数,使用功能函数完成各种需求,一般用作测试

整体结构图为:





这里详细说下插入操作和删除操作:



插入操作:

如图






插入元素方法:

判断表和插入位置是否合法

由表头开始通过next域移动pos次后,当前元素的next域为要插入的位置

判断是否为空表

是空表的话进行空表插入

不是空表的话判断是否为头插,如果是头插的话进行头插

不是空表且不是头插则为正常情况和尾插,则进行正常情况的插入

表长度加1



删除操作:

如图






删除元素方法:

判断表和插入位置是否合法

由表头开始通过next域移动pos次后,当前元素的next指向的元素为要删除的元素

判断长度是否为1,如果为1的话则直接清空表

判断是否为头删

是头删的话,进行头删

不是头删的话则为尾删和正常情况,则按正常情况删除

表长度减1

如果游标指向的是要删除的元素,则后移,指向next





OK! 上代码:

DLinkCircleList.h :

[cpp] view
plaincopy

#ifndef _DLINKCIRCLELIST_H_

#define _DLINKCIRCLELIST_H_



typedef void DLinkCircleList;

typedef struct _tag_DLinkCircleListNode DLinkCircleListNode;



struct _tag_DLinkCircleListNode

{

DLinkCircleListNode* next;

DLinkCircleListNode* pre;

};



DLinkCircleList* DLinkCircleList_Create();



void DLinkCircleList_Dstroy(DLinkCircleList* list);



void DLinkCircleList_Clear(DLinkCircleList* list);



int DLinkCircleList_Length(DLinkCircleList* list);



int DLinkCircleList_Insert(DLinkCircleList* list, DLinkCircleListNode* node, int pos);



DLinkCircleListNode* DLinkCircleList_Get(DLinkCircleList* list, int pos);



DLinkCircleListNode* DLinkCircleList_Delete(DLinkCircleList* list, int pos);



DLinkCircleListNode* DLinkCircleList_DeleteNode(DLinkCircleList* list, DLinkCircleListNode* node);



DLinkCircleListNode* DLinkCircleList_Reset(DLinkCircleList* list);



DLinkCircleListNode* DLinkCircleList_Current(DLinkCircleList* list);



DLinkCircleListNode* DLinkCircleList_Next(DLinkCircleList* list);



DLinkCircleListNode* DLinkCircleList_Pre(DLinkCircleList* list);



#endif



DLinkCircleList.c :



[cpp] view
plaincopy

#include <stdio.h>

#include <malloc.h>

#include "DLinkCircleList.h"



typedef struct _tag_DLinkCircleList

{

DLinkCircleListNode header;

DLinkCircleListNode* slider;

int length;

}TDLinkCircleList;



DLinkCircleList* DLinkCircleList_Create()

{

TDLinkCircleList* sList = (TDLinkCircleList*)malloc(sizeof(TDLinkCircleList));



if(NULL != sList)

{

sList->header.next = NULL;

sList->header.pre = NULL;

sList->slider = NULL;

sList->length = 0;

}



return sList;

}



void DLinkCircleList_Destroy(DLinkCircleList* list)

{

free(list);

}



void DLinkCircleList_Clear(DLinkCircleList* list)

{

TDLinkCircleList* sList = (TDLinkCircleList*)list;



if(NULL != sList)

{

sList->header.next = NULL;

sList->header.pre = NULL;

sList->slider = NULL;

sList->length = 0;

}

}



int DLinkCircleList_Length(DLinkCircleList* list)

{

TDLinkCircleList* sList = (TDLinkCircleList*)list;



int ret = -1;



if(NULL != sList)

{

ret = sList->length;

}



return ret;

}



int DLinkCircleList_Insert(DLinkCircleList* list, DLinkCircleListNode* node, int pos)

{

TDLinkCircleList* sList = (TDLinkCircleList*)list;



int ret = (NULL!=sList)&&(NULL!=node)&&(0<=pos);



int i = 0;



if(ret)

{

DLinkCircleListNode* current = (DLinkCircleListNode*)sList;

DLinkCircleListNode* next = NULL;



for(i=0; (i<pos)&&(NULL!=current->next); i++)

{

current = current->next;

}



next = current->next;

current->next = node;



if(0 == sList->length)

{

node->next = node;

node->pre = node;

sList->slider = node;

}

else

{

if(current == (DLinkCircleListNode*)sList)

{

node->next = next;

(next->pre)->next = node;

node->pre = next->pre;

next->pre = node;

}

else

{

node->next = next;

next->pre = node;

node->pre = current;

}

}



sList->length++;

}



return ret;

}



DLinkCircleListNode* DLinkCircleList_Get(DLinkCircleList* list, int pos)

{

TDLinkCircleList* sList = (TDLinkCircleList*)list;



DLinkCircleListNode* ret = NULL;



int i = 0;



if((NULL!=sList)&&(0<=pos)&&(0<sList->length))

{

DLinkCircleListNode* current = (DLinkCircleListNode*)sList;



for(i=0; (i<pos)&&(NULL!=current->next); i++)

{

current = current->next;

}



ret = current->next;

}



return ret;

}



DLinkCircleListNode* DLinkCircleList_Delete(DLinkCircleList* list, int pos)

{

TDLinkCircleList* sList = (TDLinkCircleList*)list;



DLinkCircleListNode* ret = NULL;



int i = 0;



if((NULL!=sList)&&(0<=pos)&&(0<sList->length))

{

DLinkCircleListNode* current = (DLinkCircleListNode*)sList;

DLinkCircleListNode* next = NULL;



for(i=0; (i<pos)&&(NULL!=current->next); i++)

{

current = current->next;

}



if(1 == sList->length)

{

ret = sList->header.next;

DLinkCircleList_Clear(sList);



return ret;

}



ret = current->next;

next = ret->next;

current->next = next;



if(current == (DLinkCircleListNode*)sList)

{

next->pre = ret->pre;

(ret->pre)->next = next;

}

else

{

next->pre = current;

}



sList->length--;



if(ret == sList->slider)

{

sList->slider = next;

}

}



return ret;

}



DLinkCircleListNode* DLinkCircleList_DeleteNode(DLinkCircleList* list, DLinkCircleListNode* node)

{

TDLinkCircleList* sList = (TDLinkCircleList*)list;



DLinkCircleListNode* ret = NULL;



int i = 0;



if((NULL!=sList)&&(NULL!=node))

{

DLinkCircleListNode* current = (DLinkCircleListNode*)sList;



for(i=0; i<sList->length; i++)

{

if(node == current->next)

{

ret = current->next;

break;

}



current = current->next;

}



if(NULL != ret)

{

DLinkCircleList_Delete(sList, i);

}

}



return ret;

}



DLinkCircleListNode* DLinkCircleList_Reset(DLinkCircleList* list)

{

TDLinkCircleList* sList = (TDLinkCircleList*)list;



DLinkCircleListNode* ret = NULL;



if(NULL!=sList)

{

sList->slider = sList->header.next;

ret = sList->slider;

}



return ret;

}



DLinkCircleListNode* DLinkCircleList_Current(DLinkCircleList* list)

{

TDLinkCircleList* sList = (TDLinkCircleList*)list;



DLinkCircleListNode* ret = NULL;



if(NULL!=sList)

{

ret = sList->slider;

}



return ret;

}



DLinkCircleListNode* DLinkCircleList_Next(DLinkCircleList* list)

{

TDLinkCircleList* sList = (TDLinkCircleList*)list;



DLinkCircleListNode* ret = NULL;



if((NULL!=sList)&&(NULL!=sList->slider))

{

ret = sList->slider;

sList->slider = ret->next;

}



return ret;

}



DLinkCircleListNode* DLinkCircleList_Pre(DLinkCircleList* list)

{

TDLinkCircleList* sList = (TDLinkCircleList*)list;



DLinkCircleListNode* ret = NULL;



if((NULL!=sList)&&(NULL!=sList->slider))

{

ret = sList->slider;

sList->slider = ret->pre;

}



return ret;

}



Main.c :

[cpp] view
plaincopy

#include <stdio.h>

#include <stdlib.h>

#include "DLinkCircleList.h"



typedef struct _tag_Value

{

DLinkCircleListNode header;

int v;

}Value;



int main(void)

{

DLinkCircleList* list = DLinkCircleList_Create();



Value v1,v2,v3,v4,v5;



Value* pV = NULL;



int i = 0;



v1.v=1, v2.v=2, v3.v=3, v4.v=4, v5.v=5;



DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v1, DLinkCircleList_Length(list));

DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v2, DLinkCircleList_Length(list));

DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v3, DLinkCircleList_Length(list));

DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v4, DLinkCircleList_Length(list));

DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v5, DLinkCircleList_Length(list));



for(i=0; i<DLinkCircleList_Length(list); i++)

{

pV = (Value*)DLinkCircleList_Get(list, i);



printf("已发现节点:%d\n", pV->v);

}

printf("\n");



DLinkCircleList_Delete(list, 0);

DLinkCircleList_DeleteNode(list, &v3);



DLinkCircleList_Destroy(list);



return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: