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

数据结构(17)双向链表

2015-08-11 14:48 423 查看
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。而之前的单链表为单向链表,双向链表也就是在单链表的结点中增加一个指向其前驱的pre指针。

如图






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

l 创建双向链表

l 销毁双向链表

l 清空双向链表

l 获取表长度

l 把node插入pos位置

l 获取pos位置的元素

l 删除pos位置的元素

l 删除表中与node相同的元素(删除第一个匹配成功的)

l 重置游标

l 返回游标所指向的结点

l 游标后移

l 游标前移



代码总分为三个文件:

DLinkList.h : 放置功能函数的声明,以及表的声明,表结点的定义

DLinkList.c : 放置功能函数的定义,以及表的定义

Main.c : 主函数,使用功能函数完成各种需求,一般用作测试

整体结构图为:








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



插入操作:

如图








插入元素方法:

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

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

Current的next域指向node

Node的next域指向next

判断是否为尾插,如果不是的话next的pre域指向node

判断是否为头插,如果是的话node的pre域指向NULL

如果之前表为空表,则游标指向插入的结点

表长度加1



删除操作:

如图






删除元素方法:

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

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

把current的next域指向next

判断是否为尾插,如果不是的话,next的pre指针指向current

如果不是尾插且是头插的话,next的pre指针指向NULL

如果删除的结点正好游标也指向它,则游标后移

表长度减1



OK! 上代码:

DLinkList.h :



[cpp] view
plaincopy

#ifndef _DLINKLIST_H_

#define _DLINKLIST_H_



typedef void DLinkList;

typedef struct _tag_DLinkListNode DLinkListNode;



struct _tag_DLinkListNode

{

DLinkListNode* next;

DLinkListNode* pre;

};



DLinkList* DLinkList_Create();



void DLinkList_Destroy(DLinkList* list);



void DLinkList_Clear(DLinkList* list);



int DLinkList_Length(DLinkList* list);



int DLinkList_Insert(DLinkList* list, DLinkListNode* node, int pos);



DLinkListNode* DLinkList_Get(DLinkList* list, int pos);



DLinkListNode* DLinkList_Delete(DLinkList* list, int pos);



DLinkListNode* DLinkList_DeleteNode(DLinkList* list, DLinkListNode* node);



DLinkListNode* DLinkList_Reset(DLinkList* list);



DLinkListNode* DLinkList_Current(DLinkList* list);



DLinkListNode* DLinkList_Next(DLinkList* list);



DLinkListNode* DLinkList_Pre(DLinkList* list);



#endif



DLinkList.c :

[cpp] view
plaincopy

#include <stdio.h>

#include <malloc.h>

#include "DLinkList.h"



typedef struct _tag_DLinkList

{

DLinkListNode header;

DLinkListNode* slider;

int length;

}TDLinkList;



DLinkList* DLinkList_Create()

{

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



if(NULL != sList)

{

sList->header.next = NULL;

sList->header.pre = NULL;

sList->slider = NULL;

sList->length = 0;

}



return sList;

}



void DLinkList_Destroy(DLinkList* list)

{

free(list);

}



void DLinkList_Clear(DLinkList* list)

{

TDLinkList* sList = (TDLinkList*)list;



if(NULL != sList)

{

sList->header.next = NULL;

sList->header.pre = NULL;

sList->slider = NULL;

sList->length = 0;

}

}



int DLinkList_Length(DLinkList* list)

{

TDLinkList* sList = (TDLinkList*)list;



int ret = -1;



if(NULL != sList)

{

ret = sList->length;

}



return ret;

}



int DLinkList_Insert(DLinkList* list, DLinkListNode* node, int pos)

{

TDLinkList* sList = (TDLinkList*)list;



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



int i = 0;



if(ret)

{

DLinkListNode* current = (DLinkListNode*)sList;

DLinkListNode* next = NULL;



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

{

current = current->next;

}



next = current->next;

current->next = node;

node->next = next;



if(NULL != next)

{

next->pre = node;

}

node->pre = current;



if(0 == sList->length)

{

sList->slider = node;

}



if(current == (DLinkListNode*)sList)

{

node->pre = NULL;

}



sList->length++;

}



return ret;

}



DLinkListNode* DLinkList_Get(DLinkList* list, int pos)

{

TDLinkList* sList = (TDLinkList*)list;



DLinkListNode* ret = NULL;



int i = 0;



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

{

DLinkListNode* current = (DLinkListNode*)sList;



for(i=0; i<pos; i++)

{

current = current->next;

}



ret = current->next;

}



return ret;

}



DLinkListNode* DLinkList_Delete(DLinkList* list, int pos)

{

TDLinkList* sList = (TDLinkList*)list;



DLinkListNode* ret = NULL;



int i = 0;



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

{

DLinkListNode* current = (DLinkListNode*)sList;

DLinkListNode* next = NULL;



for(i=0; i<pos; i++)

{

current = current->next;

}



ret = current->next;

next = ret->next;

current->next = next;



if(NULL != next)

{

next->pre = current;



if(current == (DLinkListNode*)sList)

{

next->pre = NULL;

}

}



if(ret == sList->slider)

{

sList->slider = next;

}



sList->length--;

}



return ret;

}



DLinkListNode* DLinkList_DeleteNode(DLinkList* list, DLinkListNode* node)

{

TDLinkList* sList = (TDLinkList*)list;



DLinkListNode* ret = NULL;



int i = 0;



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

{

DLinkListNode* current = (DLinkListNode*)sList;



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

{

if(node == current->next)

{

ret = current->next;

break;

}



current = current->next;

}



if(NULL != ret)

{

DLinkList_Delete(sList, i);

}

}



return ret;

}



DLinkListNode* DLinkList_Reset(DLinkList* list)

{

TDLinkList* sList = (TDLinkList*)list;



DLinkListNode* ret = NULL;



if(NULL != sList)

{

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

ret = sList->slider;

}



return ret;

}



DLinkListNode* DLinkList_Current(DLinkList* list)

{

TDLinkList* sList = (TDLinkList*)list;



DLinkListNode* ret = NULL;



if(NULL != sList)

{

ret = sList->slider;

}



return ret;

}



DLinkListNode* DLinkList_Next(DLinkList* list)

{

TDLinkList* sList = (TDLinkList*)list;



DLinkListNode* ret = NULL;



if(NULL != sList)

{

ret = sList->slider;

sList->slider = ret->next;

}&n`sp;



return ret;

}



DLinkListNode* DLinkList_Pre(DLinkList* list)

{

TDLinkList* sList = (TDLinkList*)list;



DLinkListNode* ret = NULL;



if(NULL != sList)

{

ret = sList->slider;

sList->slider = ret->pre;

}



return ret;

}



Main.c :

[cpp] view
plaincopy

#include <stdio.h>

#include <stdlib.h>

#include "DLinkList.h"



typedef struct _tag_Value

{

DLinkListNode header;

int v;

}Value;



int main(void)

{

DLinkList* list = DLinkList_Create();



int i = 0;



Value* pV = NULL;



Value v1,v2,v3,v4,v5;



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



DLinkList_Insert(list, (DLinkListNode*)&v1, DLinkList_Length(list));

DLinkList_Insert(list, (DLinkListNode*)&v2, DLinkList_Length(list));

DLinkList_Insert(list, (DLinkListNode*)&v3, DLinkList_Length(list));

DLinkList_Insert(list, (DLinkListNode*)&v4, DLinkList_Length(list));

DLinkList_Insert(list, (DLinkListNode*)&v5, DLinkList_Length(list));



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

{

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



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

}

printf("\n");



DLinkList_Delete(list, DLinkList_Length(list)-1);

DLinkList_Delete(list, 0);



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

{

pV = (Value*)DLinkList_Next(list);



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

}

printf("\n");



DLinkList_Reset(list);

DLinkList_Next(list);

pV = (Value*)DLinkList_Current(list);

printf("%d\n", pV->v);



DLinkList_DeleteNode(list, (DLinkListNode*)pV);

pV = (Value*)DLinkList_Current(list);

printf("%d\n", pV->v);



DLinkList_Pre(list);

pV = (Value*)DLinkList_Current(list);

printf("%d\n", pV->v);



printf("Length: %d\n", DLinkList_Length(list));



DLinkList_Destroy(list);



return 0;

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