双向链表的理论知识与api的设计实现

一、单向链表的局限:单向链表的节点都只有一个指向下一个节点的指针;单向链表的数据元素无法直接访问其前驱元素;逆序访问单向链表中的元素是极其耗时的操作。

二、双向链表的定义:在单向链表的结点基础上增加一个指向其前驱的pre指针。

三、双向链表的所有操作:
    1. 创建链表
    2. 销毁链表

    3. 获取链表的长度
    4. 清空链表
    5. 获取第pos个元素
    6. 插入元素到位置pos

    7. 删除位置pos处的元素
    双向链表新增操作:
    1. 获取当前游标指向的数据元素
    2. 将游标重置指向链表中的第一个数据元素
    3. 将游标移动指向到链表中的上一个数据元素
    4. 将游标移动指向到链表中的下一个数据元素

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

四、优缺点:
    优点:双向链表在单向链表的基础上增加了指向前驱的指针,功能上双向链表可以完全取代单链表的使用,双向链表可以高效的遍历链表中的所有元素。

    缺点:代码复杂度提高。

五、插入与删除:

六、设计与实现

#ifndef _ZCH_DLINKLIST_H_
#define _ZCH_DLINKLIST_H_

typedef void DLinkList;

typedef struct _tag_DLinkListNode
{
	struct _tag_DLinkListNode* next;
	struct _tag_DLinkListNode * pre;
}DLinkListNode;

DLinkList* Create();

void Destroy(DLinkList* list);

void Clear(DLinkList* list);

int Length(DLinkList* list);

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

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

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

//add
DLinkListNode* DeleteNode(DLinkList* list, DLinkListNode* node);

DLinkListNode* Reset(DLinkList* list);

DLinkListNode* Current(DLinkList* list);

DLinkListNode* Next(DLinkList* list);

DLinkListNode* Pre(DLinkList* list);

#endif
#include <stdio.h>
#include <malloc.h>
#include "zch_dlinklist.h"

typedef struct _tag_DLinkList
{
    DLinkListNode header;
    DLinkListNode* slider;
    int length;
}TDLinkList;

DLinkList* Create()
{
    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 Destory(DLinkList* list)
{
    if(list != NULL)
    {
        free(list);
    }
}

void Clear(DLinkList* list)
{
    TDLinkList* dList = (TDLinkList*)list;

    if(dList != NULL)
    {
        dList->length = 0;
        dList->header.next = NULL;
        dList->header.pre = NULL;
        dList->slider = NULL;
    }
}

int Length(DLinkList* list)
{
    TDLinkList* dList = (TDLinkList*)list;

    if(NULL == dList)
    {
        return -1;
    }
    return dList->length;
}

int Insert(DLinkList* list, DLinkListNode* node, int pos)
{
    int i = 0;
    TDLinkList* dList = (TDLinkList*)list;

    if(dList == NULL || node == NULL || pos < 0)
    {
        return -1;
    }
    //指向头节点
    DLinkListNode* current = (DLinkListNode*)dList;
    //需增加第二个辅助指针
    DLinkListNode* node = NULL;

    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(dList->length == 0)
    {
        dList->slider = node;//插入第一个元素的时候,游标指向第一个元素
    }

    //若在0位置插入
    if(current == (DLinkListNode*)dList)
    {
        node->pre = NULL;
    }
    dList->length++;
    return 0;
}

DLinkListNode* GetEle(DLinkList* list, int pos)
{
    TDLinkList* dList = (TDLinkList*)list;
    DLinkListNode* ret = NULL;
    int i = 0;

    if((dList != NULL) && (0 <= pos) && (pos < dList->length))
    {
        DLinkListNode* current = (DLinkListNode*)dList;

        for(i = 0; i < pos; i++)
        {
            current = current->next;
        }
        ret = current->next;
    }
    return ret;
}

DLinkListNode* Delete(DLinkList* list, int pos)
{
    TDLinkList* dList = (TDLinkList*)list;
    DLinkListNode* ret = NULL;
    int i = 0;
    if(dList == NULL || pos < 0)
    {
        return NULL;
    }

    DLinkListNode* current = (DLinkListNode*)dList;
    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*)dList)
        {
            next->pre = NULL;
        }
    }
    if(dList->slider == ret)
    {
        dList->slider = next;
    }
    dList->length--;

    return ret;
}

DLinkListNode* DeleteNode(DLinkList* list, DLinkListNode* node)
{
    TDLinkList* dList = (TDLinkList*)list;
    DLinkListNode* ret = NULL;
    int i = 0;

    if(dList != NULL)
    {
        DLinkListNode* current = (DLinkListNode*)dList;

        for(i = 0; i < dList->length; i++)
        {
            if(current->next == node)
            {
                ret = current->next;
                break;
            }
            current = current->next;
        }
        if(ret != NULL)
        {
            Delete(dList, i);
        }
    }
    return ret;
}

DLinkListNode* Reset(DLinkList* list)
{
    TDLinkList* dList = (TDLinkList*)list;
    DLinkListNode* ret = NULL;
    if(dList != NULL)
    {
        dList->slider = dList->header.next;
        ret = dList->slider;
    }
    return ret;
}

DLinkListNode* Current(DLinkList* list)
{
    TDLinkList* dList = (TDLinkList*)list;
    DLinkListNode* ret = NULL;

    if(dList != NULL)
    {
        ret = dList->slider;
    }
    return ret;
}

DLinkListNode* Next(DLinkList* list)
{
    TDLinkList* dList = (TDLinkList*)list;
    DLinkListNode* ret = NULL;
    if((dList != NULL) && (dList->slider != NULL))
    {
        ret = dList->slider;
        dList->slider = ret->next;
    }
    return ret;
}

DLinkListNode* Pre(DLinkList* list)
{
    TDLinkList* dList = (TDLinkList*)list;
    DLinkListNode* ret = NULL;
    if((dList != NULL) && (dList->slider != NULL))
    {
        ret = dList->slider;
        dList->slider = ret->pre;
    }
    return ret;
}

猜你喜欢

转载自blog.csdn.net/qq_31990987/article/details/80791310
今日推荐