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;
}

 

 

 

 

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