• 双向链表总结


    基本数据结构之-双向链表

    双向链表和单向链表明显的区别就是,双向链表可以向前查找,也就是能直接找到它自己的前驱结点,但是双向链表不是循环链表!

    分析基本的数据结构,每个结点都有自己的数据域和两个指针域,一个指向前驱,一个指向后继,但是为了通用性,我们只考虑一个前驱和一个后继的关系

    typedef struct _DOUBLE_LIST_NODE

    {

        // 定义双向链表的前驱和后继

        struct _DOUBLE_LIST_NODE *Pre;

        struct _DOUBLE_LIST_NODE  *Next;

    }DoubleListNode, *DoubleSidedList;

    // 初始化

    int Init_DoubleSidedList(DoubleSidedList *doublesidedlist)

    {

        if (doublesidedlist == NULL)

        {

            exit(-1);

        }

        if (*doublesidedlist == NULL)

        {

            *doublesidedlist = (DoubleSidedList)malloc(sizeof(DoubleListNode));

        }

        (*doublesidedlist)->Next = NULL;

        (*doublesidedlist)->Pre = NULL;

     

        return 0;

    }

    // 销毁,不要释放其他位置的空间,不知道是栈内存还是堆内存,并且不知道是什么数据类型

    void Destroy_DoubleSidedList(DoubleSidedList doublesidedlist)

    {

        if (doublesidedlist == NULL)

        {

            return;

        }

        free(doublesidedlist);

    }

     

    // 仅仅是把指针置空

    void Clear_DoubleSidedList(DoubleSidedList doublesidedlist)

    {

        if (doublesidedlist == NULL)

        {

            return;

        }

        doublesidedlist->Next = NULL;

        doublesidedlist->Pre = NULL;

    }

     

    int Empty_DoubleSidedList(DoubleSidedList doublesidedlist)

    {

        if (doublesidedlist==NULL)

        {

            return -1;

        }

        // 如果next为空,肯定链表也是空的

        return doublesidedlist->Next == NULL;

        //

    }

     

    // 返回当前双向链表的长度

    int Length_DoubleSidedList(DoubleSidedList doublesidedlist)

    {

        if (doublesidedlist == NULL)

        {

            return 0;

        }

        int length = 0;

        // 第一个元素的开始的位置在 定义Next开始

        DoubleListNode *pCurrent =doublesidedlist->Next;

     

        while (pCurrent!= NULL)

        {

            ++length;

            pCurrent = pCurrent->Next;

        }

        return length;

    }

     

    void * GetElem_DoubleSidedList(DoubleSidedList doublesidedlist, int Pos)

    {

        if (doublesidedlist == NULL)

        {

            return NULL;

        }

        if (Pos<0 || Pos>Length_DoubleSidedList(doublesidedlist)-1)

        {

            return NULL;

        }

        DoubleListNode *pCurrent = doublesidedlist->Next;

        int i = 0;

        while (i<Pos)

        {

            pCurrent = pCurrent->Next;

            ++i;

        }

        // 返回所在的位置 从 0 开始

        return pCurrent;

    }

    // 查看链表中是否存在某个值,返回所在的位置

    int  LocateElem_DoubleSidedList(DoubleSidedList doublesidedlist, void* data, int(*compare)(void *data1, void *data2))

    {

        if (doublesidedlist==NULL)

        {

            return -1;

        }

        if (data == NULL)

        {

            return -2;

        }

        if (compare == NULL)

        {

            return -4;

        }

        DoubleListNode *Node = (DoubleListNode *)data;

        int i = 0;

        DoubleListNode *pCurrent = doublesidedlist->Next;

     

        while (pCurrent!= NULL)

        {

            // 必须要传入比较函数

            if (compare(pCurrent, Node))

            {

                return i;

            }

            pCurrent = pCurrent->Next;

            ++i;

        }

        return -3;

    }

    // 返回前驱,这儿就可以体现出双向链表的优势

    void *PriorElem_DoubleSidedList(DoubleSidedList doublesidedlist, void *data)

    {

        if (doublesidedlist == NULL)

        {

            return NULL;

        }

        if (data == NULL)

        {

            return NULL;

        }

     

        DoubleListNode *pCurrent = doublesidedlist->Next;

     

        while (pCurrent != NULL)

        {

    #if 0

     

            if (pCurrent->Next==data)

            {

                return pCurrent;

            }

     

    #else

     

            if (pCurrent == data)

            {

                //这就是双向链表的好处

                return pCurrent->Pre;

            }

           

    #endif

            pCurrent = pCurrent->Next;

        }

        return NULL;

    }

    // 返回后继

    void* NextElem_DoubleSidedList(DoubleSidedList doublesidedlist, void *data)

    {

        if (doublesidedlist == NULL)

        {

            return NULL;

        }

        if (data == NULL)

        {

            return NULL;

        }

     

        DoubleListNode *pCurrent = doublesidedlist;

     

        while (pCurrent->Next != NULL)

        {

            if (pCurrent == data)

            {

                return pCurrent->Next;

            }

            pCurrent = pCurrent->Next;

        }

        return NULL;

    }

     

    // 插入操作,一定要考虑特殊的情况

    int Insert_DoubleSidedList(DoubleSidedList doublesidedlist, int Pos, void * data)

    {

        if (doublesidedlist == NULL)

        {

            return -1;

        }

        if (data == NULL)

        {

            return -2;

        }

        if (Pos < 0)

        {

            Pos = 0;

        }

        if (Pos > Length_DoubleSidedList(doublesidedlist))

        {

            Pos = Length_DoubleSidedList(doublesidedlist);

        }

     

        DoubleListNode *pCurrent = doublesidedlist;

     

        for (int i = 0; i < Pos; ++i)

        {

            pCurrent = pCurrent->Next;

        }

        DoubleListNode *Node = (DoubleListNode *)data;

       

        //

        if (Pos==0 && Length_DoubleSidedList(doublesidedlist) == 0)

        {

            // 最前面一个位置插入 && 当前长度为0 插入的结点不存在后继结点

                Node->Next = pCurrent->Next;

                Node->Pre = pCurrent;

                pCurrent->Next = Node;

        }

        else if (Length_DoubleSidedList(doublesidedlist) == Pos)

        {

            // 最后一个结点不存在后继结点

            Node->Next = pCurrent->Next;

            Node->Pre = pCurrent;

            pCurrent->Next = Node;

        }

        else

        {

            Node->Next = pCurrent->Next;

            pCurrent->Next->Pre = Node;

            pCurrent->Next = Node;

            Node->Pre = pCurrent;

        }

       

     

        return 0;

    }

     

    // 删除操作 一定要考虑特殊的情况

    int  DeleteByPos_DoubleSidedList(DoubleSidedList doublesidedlist, int Pos)

    {

        if (doublesidedlist == NULL)

        {

            return -1;

        }

        if (Pos<0 || Pos>Length_DoubleSidedList(doublesidedlist) - 1)

        {

            return -2;

        }

        DoubleListNode *pCurrent = doublesidedlist->Next;

        // 找到前驱

     

        for (int i = 0; i < Pos; ++i)

        {

            pCurrent = pCurrent->Next;

        }

        // 如果删除的是最后一个结点,那么找不到最后一个结点的下一个结点

        if (Pos == Length_DoubleSidedList(doublesidedlist))

        {

            pCurrent->Pre->Next = NULL;

        }

        else

        {

            pCurrent->Next->Pre = pCurrent;

            pCurrent->Next = pCurrent->Next->Next;

        }

       

        return 0;

     

    }

     

    int  DeleteByVal_DoubleSidedList(DoubleSidedList doublesidedlist, void* data)

    {

        if (doublesidedlist == NULL)

        {

            return -1;

        }

        DoubleListNode *pCurrent = doublesidedlist->Next;

     

        while (pCurrent->Next != NULL )

        {

            if (pCurrent == data)

            {

                break;

            }

            pCurrent = pCurrent->Next;

        }

        // 如果是最后一个结点,

        if (pCurrent->Next == NULL)

        {

            pCurrent->Pre->Next = NULL;

        }

        else

        {

            pCurrent->Next->Pre = pCurrent;

            pCurrent->Next = pCurrent->Next->Next;

        }

       

        return 0;

    }

    // 遍历操作

    void Traverse_DoubleSidedList(DoubleSidedList doublesidedlist, void(*Traverse)(void *data))

    {

        if (doublesidedlist == NULL)

        {

            return;

        }

        if (Traverse == NULL)

        {

            return;

        }

        DoubleListNode *pCurrent = doublesidedlist->Next;

        while (pCurrent != NULL)

        {

            Traverse(pCurrent);

            pCurrent = pCurrent->Next;

        }

    }

  • 相关阅读:
    BZOJ1858[Scoi2010]序列操作 题解
    BZOJ3631[JLOI2014]松鼠的新家 题解
    BZOJ1036[ZJOI2008]树的统计Count 题解
    BZOJ1798[Ahoi2009]Seq 维护序列seq 题解
    BZOJ3212 Pku3468 A Simple Problem with Integers 题解
    BZOJ1012[JSOI2008]最大数maxnumber 题解
    洛谷P1080 国王游戏
    洛谷 P2296 寻找道路
    洛谷P1970 花匠
    洛谷 P1969 积木大赛
  • 原文地址:https://www.cnblogs.com/bkcarlos/p/5935257.html
Copyright © 2020-2023  润新知