数据结构-双向链表(学习笔记)

来源:互联网 发布:图片加白边是什么软件 编辑:程序博客网 时间:2024/06/05 18:07

定义:

在单链表的结点中增加一个指向其前驱的pre指针

 双向链表的新操作:

1.将游标重置指向链表中的第一

2.将游标重置指向链表中的第一个数据元

3.将游标移动指向到链表中的下一个数据元

4.将游标移动指向到链表中的上一个数据元素

5.直接指定删除链表中的某个数据元素

头文件:

#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
c文件

#include <stdio.h>#include <malloc.h>#include "DLinkList.h"typedef struct _tag_DLinkList{    DLinkListNode header;    DLinkListNode* slider;    int length;} TDLinkList;DLinkList* DLinkList_Create() // O(1){    TDLinkList* ret = (TDLinkList*)malloc(sizeof(TDLinkList));        if( ret != NULL )    {        ret->length = 0;        ret->header.next = NULL;        ret->header.pre = NULL;        ret->slider = NULL;    }        return ret;}void DLinkList_Destroy(DLinkList* list) // O(1){    free(list);}void DLinkList_Clear(DLinkList* list) // O(1){    TDLinkList* sList = (TDLinkList*)list;        if( sList != NULL )    {        sList->length = 0;        sList->header.next = NULL;        sList->header.pre = NULL;        sList->slider = NULL;    }}int DLinkList_Length(DLinkList* list) // O(1){    TDLinkList* sList = (TDLinkList*)list;    int ret = -1;        if( sList != NULL )    {        ret = sList->length;    }        return ret;}int DLinkList_Insert(DLinkList* list, DLinkListNode* node, int pos) // O(n){     TDLinkList* sList = (TDLinkList*)list;    int ret = (sList != NULL) && (pos >= 0) && (node != NULL);    int i = 0;        if( ret )    {        DLinkListNode* current = (DLinkListNode*)sList;        DLinkListNode* next = NULL;        //找出pos对应的元素         for(i=0; (i<pos) && (current->next != NULL); i++)        {            current = current->next;        }        //获取下一个元素         next = current->next;        //指向添加的元素         current->next = node;        //连接上之前元素         node->next = next;                if( next != NULL )        {            next->pre = node;        }                node->pre = current;                if( sList->length == 0 )        {            node->pre = NULL;            sList->slider = node;        }                sList->length++;    }        return ret;}DLinkListNode* DLinkList_Get(DLinkList* list, int pos) // O(n){    TDLinkList* sList = (TDLinkList*)list;    DLinkListNode* ret = NULL;    int i = 0;        if( (sList != NULL) && (0 <= pos) && (pos < 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) // O(n){    TDLinkList* sList = (TDLinkList*)list;    DLinkListNode* ret = NULL;    int i = 0;        if( (sList != NULL) && (0 <= pos) && (pos < 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( next != NULL )        {            next->pre = current;                        if( current == (DLinkListNode*)sList )            {                next->pre = NULL;            }        }                if( sList->slider == ret )        {            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( sList != NULL )    {        DLinkListNode* current = (DLinkListNode*)sList;                for(i=0; i<sList->length; i++)        {            if( current->next == node )            {                ret = current->next;                break;            }                        current = current->next;        }                if( ret != NULL )        {            DLinkList_Delete(sList, i);        }    }        return ret;}DLinkListNode* DLinkList_Reset(DLinkList* list){    TDLinkList* sList = (TDLinkList*)list;    DLinkListNode* ret = NULL;        if( sList != NULL )    {        sList->slider = sList->header.next;        ret = sList->slider;    }        return ret;}DLinkListNode* DLinkList_Current(DLinkList* list){    TDLinkList* sList = (TDLinkList*)list;    DLinkListNode* ret = NULL;        if( sList != NULL )    {        ret = sList->slider;    }        return ret;}DLinkListNode* DLinkList_Next(DLinkList* list){    TDLinkList* sList = (TDLinkList*)list;    DLinkListNode* ret = NULL;        if( (sList != NULL) && (sList->slider != NULL) )    {        ret = sList->slider;        sList->slider = ret->next;    }        return ret;}DLinkListNode* DLinkList_Pre(DLinkList* list){    TDLinkList* sList = (TDLinkList*)list;    DLinkListNode* ret = NULL;        if( (sList != NULL) && (sList->slider != NULL) )    {        ret = sList->slider;        sList->slider = ret->pre;    }        return ret;}
main 文件

#include <stdio.h>#include <stdlib.h>#include "DLinkList.h"/* run this program using the console pauser or add your own getch, system("pause") or input loop */struct Value{    DLinkListNode header;    int v;};/* run this program using the console pauser or add your own getch, system("pause") or input loop */int main(int argc, char *argv[]) {int i = 0;    DLinkList* list = DLinkList_Create();    struct Value* pv = NULL;    struct Value v1;    struct Value v2;    struct Value v3;    struct Value v4;    struct Value 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 = (struct 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 = (struct Value*)DLinkList_Next(list);                printf("%d\n", pv->v);    }        printf("\n");        DLinkList_Reset(list);    DLinkList_Next(list);        pv = (struct Value*)DLinkList_Current(list);        printf("%d\n", pv->v);        DLinkList_DeleteNode(list, (DLinkListNode*)pv);        pv = (struct Value*)DLinkList_Current(list);        printf("%d\n", pv->v);        DLinkList_Pre(list);        pv = (struct Value*)DLinkList_Current(list);        printf("%d\n", pv->v);        printf("Length: %d\n", DLinkList_Length(list));        DLinkList_Destroy(list);return 0;}



总结:

1. 双向链表在单链表的基础上增加了指向前驱的指针

2.功能上双向链表可以完全取代单链表的使用

3.循环链表的Next,Pre和Current操作可以高效的遍历链表中的所有元素


0 0