C语言-双向链表

理解双向链表

和单链表类似,单链表是结点只包含了指向下一个结点的后继指针域,而双向链表的结点增加了一个指向前驱的指针域。这样以来方便从某一结点开始,方便访问前一个结点和后一个结点。

                    

双向链表的插入分析

一般插入:

                      

添加辅助指针current和next。

current的后继指针指向插入结点node,node结点的后继指针指向next结点处

next结点的前驱指针指向node结点,node结点的前驱指针指向current结点处

插入头部结点(0号元素):

                    

需要异常处理,辅助指针current指向头部结点,如果current的后继指针指向Null,不作处理,如果current的后继指针不为Null,则辅助指针next为current的后继指针指向得结点,current的前驱指针指向Null。

插入尾部结点:

                    

双向链表的删除分析

普通删除:

                     

删除头结点:

链表中有其他元素

删除0号元素时,应该让next的前驱指针指向Null

                    

只有一个元素

                    

删除尾结点:

                     

//DLinkList.h
#pragma once
typedef void DLinkList;

typedef struct tag_DLinkListNode
{
    struct tag_DLinkListNode *next;
    struct tag_DLinkListNode *prev;
}TDLinkListNode;

DLinkList* DLinkList_Creat();
void DLinkList_Destroy(DLinkList *list);
void DLinkList_Clear(DLinkList *list);
int DLinkList_GetLength(DLinkList *list);
int DLinkList_Inster(DLinkList *list, TDLinkListNode *node, int pos);
TDLinkListNode *DLinkList_Get(DLinkList *list, int pos);
TDLinkListNode *DLinkList_Delete(DLinkList *list, int pos);
TDLinkListNode *DLinkList_DeleteNode(DLinkList *list, TDLinkListNode *node);
TDLinkListNode *DLinkList_Reset(DLinkList *list);
TDLinkListNode *DLinkList_Current(DLinkList *list);
TDLinkListNode *DLinkList_Next(DLinkList *list);
TDLinkListNode *DLinkList_Prev(DLinkList *list);
//DLinkList .c
#pragma warning(disable : 4996)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "DLinkList.h"

typedef struct tag_DLinkList
{
    TDLinkListNode header;
    TDLinkListNode *slider;
    int length;
}TDLinkList;

DLinkList *DLinkList_Creat()
{
    TDLinkList *list = NULL;
    list = (TDLinkList *)malloc(sizeof(TDLinkList));
    memset(list, 0, sizeof(TDLinkList));
    list->header.next = NULL;
    list->header.prev = NULL;
    list->slider = NULL;
    list->length = 0;
    return list;
}

void DLinkList_Destroy(DLinkList * list)
{
    TDLinkList *temp = NULL;
    if (list == NULL)
    {
        printf("DLinkList_Destroy err: list = NULL");
        return;
    }
    temp = (TDLinkList *)list;
    free(temp);
    return;
}

void DLinkList_Clear(DLinkList *list)
{
    TDLinkList *temp = NULL;
    if (list == NULL)
    {
        printf("DLinkList_Clear err: list = NULL");
        return;
    }
    temp = (TDLinkList *)list;
    temp->length = 0;
    temp->header.next = NULL;
    temp->header.prev = NULL;
    temp->slider = NULL;
    return;
}

int DLinkList_GetLength(DLinkList *list)
{
    TDLinkList *temp = NULL;
    if (list == NULL)
    {
        printf("DLinkList_GetLength err: list = NULL");
        return -1;
    }
    temp = (TDLinkList *)list;
    return temp->length;
}

int DLinkList_Inster(DLinkList *list, TDLinkListNode *node, int pos)
{
    TDLinkList *temp = NULL;
    if (list == NULL || node == NULL || pos < 0)
    {
        printf("DLinkList_Inster err: list = NULL ||  node = NULL || pos < 0");
        return -1;
    }
    temp = (TDLinkList *)list;
    if (pos > temp->length)
    {
        printf("DLinkList_Get err: pos > temp->length");
        return -2;
    }
    TDLinkListNode *current = &(temp->header);
    TDLinkListNode *next = NULL;
    int i = 0;
    for (i = 0; i < pos; i++)
    {
        current = current->next;
    }

    //游标指向第一个插进来的节点
    if (temp->slider == NULL)
    {
        temp->slider = node;
    }
	
    //插入0号元素时
    if (current == &(temp->header))
    {
        //当插入节点的next = null(异常处理)
        if (current->next != NULL)
        {
            next = current->next;
        }
        current->prev = NULL;
    }

    next = current->next;
    current->next = node;
    node->next = next;

    //如果删除尾结点时辅助指针next = null(异常处理)
    if (next != NULL)
        next->prev = node;

    node->prev = current;

    temp->length++;
    return 0;
}

TDLinkListNode *DLinkList_Get(DLinkList *list, int pos)
{
    TDLinkList *temp = NULL;
    if (list == NULL || pos < 0)
    {
        printf("DLinkList_Get err: list = NULL");
        return NULL;
    }
    temp = (TDLinkList *)list;
    if (pos > temp->length)
    {
        printf("DLinkList_Get err: pos > temp->length");
        return NULL;
    }
    TDLinkListNode *current = &(temp->header);
    TDLinkListNode *ret = NULL;
    int i = 0;
    for (i = 0; i < pos; i++)
    {
        current = current->next;
    }
    ret = current->next;
    return ret;
}

TDLinkListNode *DLinkList_Delete(DLinkList *list, int pos)
{
    TDLinkList *temp = NULL;
    if (list == NULL || pos < 0)
    {
        printf("DLinkList_Delete err: list = NULL ||  node = NULL || pos < 0");
        return NULL;
    }
    temp = (TDLinkList *)list;
    if (pos > temp->length)
    {
        printf("DLinkList_Delete err: pos > temp->length");
        return NULL;
    }
    TDLinkListNode *current = &(temp->header);
    TDLinkListNode *next = NULL;
    TDLinkListNode *ret = NULL;
    int i = 0;
    for (i = 0; i < pos; i++)
    {
        current = current->next;
    }

    ret = current->next;
    next = ret->next;
    current->next = next;
    if (next != NULL)
    {
        next->prev = current;

        //删除0号元素
        if (current == &(temp->header))
        {
            next->prev = NULL;
        }
    }

    //删除的节点正好是游标所指的节点,那么游标下一
    if (temp->slider == ret)
        temp->slider = next;

    if (temp->length == 0)
    {
        temp->header.next = NULL;
        temp->header.prev = NULL;
        temp->slider = NULL;
    }
    temp->length--;
    return ret;
}

TDLinkListNode * DLinkList_DeleteNode(DLinkList *list, TDLinkListNode *node)
{
    if (list == NULL || node == NULL)
    {
        printf("LinkList_DeleteNode err: list = NULL || node = NULL");
        return NULL;
    }
    int i = 0;
    TDLinkList *temp = (TDLinkList *)list;
    TDLinkListNode *current = &temp->header;
    TDLinkListNode *ret = NULL;

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

TDLinkListNode * DLinkList_Reset(DLinkList * list)
{
    TDLinkList *temp = NULL;
    if (list == NULL)
    {
        printf("DLinkList_Reset err: list = NULL");
        return NULL;
    }
    temp = (TDLinkList *)list;
    temp->slider = DLinkList_Get(temp, 0);
    return temp->slider;
}

TDLinkListNode * DLinkList_Current(DLinkList * list)
{
    TDLinkList *temp = NULL;
    if (list == NULL)
    {
        printf("DLinkList_Current err: list = NULL");
        return NULL;
    }
    temp = (TDLinkList *)list;
    return temp->slider;
}

TDLinkListNode * DLinkList_Next(DLinkList * list)
{
    TDLinkList *temp = NULL;
    if (list == NULL)
    {
        printf("DLinkList_Next err: list = NULL");
        return NULL;
    }
    temp = (TDLinkList *)list;
    temp->slider = temp->slider->next;
    return temp->slider;
}

TDLinkListNode * DLinkList_Prev(DLinkList * list)
{
    TDLinkList *temp = NULL;
    if (list == NULL)
    {
        printf("DLinkList_Prev err: list = NULL");
        return NULL;
    }
    temp = (TDLinkList *)list;
    temp->slider = temp->slider->prev;
    return temp->slider;
}
//测试代码
#pragma warning(disable : 4996)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "DLinkList.h"

typedef struct tag_Value
{
    TDLinkListNode node;
    int val;
}TValue;

int main(int argc, char** argv)
{
    DLinkList *list = (DLinkList *)DLinkList_Creat();

    if (list == NULL)
    {
        printf("DLinkList_Creat err: list = NULL");
        return -1;
    }

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

    DLinkList_Inster(list, (TDLinkListNode*)&v1, DLinkList_GetLength(list));
    DLinkList_Inster(list, (TDLinkListNode*)&v2, DLinkList_GetLength(list));
    DLinkList_Inster(list, (TDLinkListNode*)&v3, DLinkList_GetLength(list));
    DLinkList_Inster(list, (TDLinkListNode*)&v4, DLinkList_GetLength(list));
    DLinkList_Inster(list, (TDLinkListNode*)&v5, DLinkList_GetLength(list));
    int i = 0;
    for (i = 0; i < DLinkList_GetLength(list); i++)
    {
        TValue *v = (TValue *)DLinkList_Get(list, i);
        printf("val = %d\n", v->val);
    }

    printf("\n");
    DLinkList_Delete(list, 0);
    DLinkList_DeleteNode(list, DLinkList_Get(list, DLinkList_GetLength(list) - 1));
    printf("%d\n", DLinkList_GetLength(list));
    for (i = 0; i < DLinkList_GetLength(list); i++)
    {
        TValue *v = (TValue *)DLinkList_Get(list, i);
        printf("val = %d\n", v->val);
    }

    printf("\n");
    DLinkList_Delete(list, 1);
    DLinkList_Reset(list);
    DLinkList_Next(list);
    TValue *v_1 = (TValue *)DLinkList_Current(list);
    printf("val = %d\n", v_1->val);
    TValue *v_2 = (TValue *)DLinkList_Prev(list);
    printf("val = %d\n", v_2->val);

    system("pause");
    return 0;
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章