双向链表的实现

单链表在向后遍历的时候,很是方便,顺着第一个节点一直往后遍历就可以了,但是如果想从后往前遍历,那就十分不方便了。而双向链表的出现,就是为了解决这个问题。下图就是一个双向链表

这里写图片描述

由上图可见,双链表相比单链表,只是比单链表多了一个向前的指针,也正是因为有这个prev指针,所以从后往前遍历,也变得容易起来。

如果想了解循环双向链表的实现,可以点击这里循环双向链表的实现

下面是双向链表的C语言实现

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>


#define LIST_MAX_LEN 10

typedef int ElemType;

typedef struct Node_T
{
    ElemType value;
    int length;
    struct Node_T * prev;
    struct Node_T * next;
}Node;

typedef struct Node_T DList;



DList * doubly_linked_list_init(void)
{
    DList * dlist = (DList *)malloc(sizeof(DList));
    if(!dlist)
    {
        printf("malloc dlist fail!\n");
        return NULL;
    }

    memset(dlist, 0, sizeof(DList));
    dlist->length = 0;
    dlist->prev = NULL;
    dlist->next = NULL; 

    return dlist;
}

bool doubly_linked_list_is_empty(DList * dlist)
{   
    return dlist->length == 0;
}

bool double_linked_list_is_full(DList * dlist)
{
    if(dlist->length >= LIST_MAX_LEN)
        return true;
    else 
        return false;
}

/*  insert value at the tail of the list   */
void doubly_linked_list_insert(DList * dlist, ElemType value)
{
    DList * pDList, * insertElem;
    pDList = dlist;

    if(dlist==NULL)
    {
        printf("list is NULL\n");
        return;
    }

    if(true == double_linked_list_is_full(dlist))
    {
        printf("list is full\n");
        return;
    }

    /* Find the tail of the list */
    while(pDList->next)
    {
        pDList = pDList->next;
    }

    insertElem = (DList *)malloc(sizeof(DList));
    if(!insertElem)
    {
        printf("malloc insertElem fail!\n");
        return;
    }
    memset(insertElem, 0, sizeof(DList));
    insertElem->next = NULL;
    insertElem->value = value;

    pDList->next = insertElem;
    insertElem->prev = pDList;

    dlist->length++;
}

/*  delete value by the param index   */
void doubly_linked_list_delete_by_index(DList * dlist, int index)
{
    int count = 0;
    DList * pDList = dlist;

    if(dlist==NULL || dlist->next==NULL)
    {
        printf("list is NULL\n");
        return;
    }
    if(index<=0 || index>=LIST_MAX_LEN || index>dlist->length)
    {
        printf("insert index is error\n");
        return;
    }

    while(pDList->next && count<index)
    {
        pDList = pDList->next;
        count ++;
    }

    if(pDList->next == NULL)
    {
        pDList->prev->next = pDList->next;
    }
    else
    {
        pDList->next->prev = pDList->prev;
        pDList->prev->next = pDList->next;
    }
    dlist->length--;
    free(pDList);       /* It need to free the delete element */
}

void doubly_linked_list_traverse_fordward(DList * dlist)
{   
    printf("fordward traverse : ");

    while(dlist->next)
    {
        printf("%3d  ", dlist->next->value);    // There have the head fo the Doubly Linked List
        dlist = dlist->next;
    }

    printf("\n");
}

void doubly_linked_list_traverse_backward(DList * dlist)
{
    printf("backward traverse : ");

    DList * pDList = dlist;

    /* find the final element */
    while(pDList->next)
        pDList = pDList->next;

    while(pDList->prev)
    {
        printf("%3d  ", pDList->value);
        pDList = pDList->prev;
    }

    printf("\n");
}

/* This implement of Doubly Linked List have the head */
void doubly_linked_list_main_test(void)
{
    DList * dlist = doubly_linked_list_init();

    doubly_linked_list_insert(dlist, 1);    
    doubly_linked_list_insert(dlist, 2);    
    doubly_linked_list_insert(dlist, 3);    
    doubly_linked_list_insert(dlist, 4);
    doubly_linked_list_insert(dlist, 5);    
    doubly_linked_list_insert(dlist, 6);    
    doubly_linked_list_insert(dlist, 7);    
    doubly_linked_list_insert(dlist, 8);    
    doubly_linked_list_insert(dlist, 9);    
    doubly_linked_list_insert(dlist, 10);       

//  doubly_linked_list_delete_by_index(dlist, 0);
    doubly_linked_list_delete_by_index(dlist, 5);

    doubly_linked_list_traverse_fordward(dlist);
    doubly_linked_list_traverse_backward(dlist);

    printf("DList len is %d\n", dlist->length);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值