双链表实例

双链表:

有时候以倒序扫描链表很方便。标准实现方法此时无能为力,然而解决解决方法却很简单,只要在数据结构上附加一个域,使他包含指向前一个指针即可。

双链表的实例可以直接拿上一遍博客的单链表来修改。当你把单链表很熟的时候,会发现双链表其实也挺简单的。

实例如下:

//dlinklist.h文件

#ifndef __DLINKLIST_H__
#define __DLINKLIST_H__

typedef struct dlinklistnode         
{
    struct dlinklistnode *next;      
    struct dlinklistnode *prev;  //多了一个指向前一个节点的指针prev    
    int item;   //自身的信息
}DLinkListNode;             //数据节点 

typedef struct dlinklist         
{
    DLinkListNode header;        
    int length;       //链表的长度

}DLinkList;               //头节点   

DLinkList *DLinkList_Create();
void DLinkList_Destroy(DLinkList *list);
void DLinkList_Clear(DLinkList *list);
int DLinkList_Length(DLinkList *list);
int DLinkList_Insert(DLinkList *list, DLinkListNode *node, int pos);
DLinkListNode *DLinkList_Get(DLinkList *list,int pos);
DLinkListNode *DLinkList_Delete(DLinkList *list,int pos);

#endif  //__DLINKLIST_H__

//dlinklist.c文件

#include <stdlib.h>

#include "dlinklist.h"

//创建
DLinkList *DLinkList_Create()
{
    DLinkList *ret = NULL;

    ret = malloc(sizeof(DLinkList));

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

    return ret;
}

//销毁
void DLinkList_Destroy(DLinkList *list)
{
    free(list);
}

//清空
void DLinkList_Clear(DLinkList *list)
{
    if(list!=NULL)
    {
        list->length =0;
        list->header.next = NULL;
        list->header.prev = NULL;
    }
}

//长度
int DLinkList_Length(DLinkList *list)
{
    int ret = -1;

    if( list!=NULL )
    {
        ret = list->length; 
    }

    return ret;
}

//插入
int DLinkList_Insert(DLinkList *list, DLinkListNode *node, int pos)
{
    int ret = list!=NULL && node!=NULL && pos>=0;

    if( ret )
    {
        int i;
        DLinkListNode *cur = (DLinkListNode *)list;
        DLinkListNode *next = NULL;

        for(i=0;i<pos && cur->next!=NULL;i++)
        {
            cur = cur->next; 
        }
        next = cur->next;

        node->next = next;
        if( cur != (DLinkListNode *)list )//判断是否插到第一个节点。
            node->prev = cur;
        else
            node->prev == NULL;
        if(next != NULL)    //判断是否插到最后
            next->prev = node;
        cur->next = node;

        list->length++;
    }

    return ret;
}

//获得
DLinkListNode *DLinkList_Get(DLinkList *list,int pos)
{
    DLinkListNode *ret = NULL;

    if( list!=NULL && (0<=pos && pos<list->length) )
    {
        int i;
        DLinkListNode *cur = (DLinkListNode *)list;

        for(i=0; i<pos; i++)
            cur = cur->next;
        ret = cur->next;        //因为从0开始计数的,要第三个数,那么就是第二个数的next
    }

    return ret;
}

//删除
DLinkListNode *DLinkList_Delete(DLinkList *list,int pos)
{
    DLinkListNode *ret = NULL;

    if(list!=NULL && (0<=pos&&pos<list->length) )
    {
        int i;
        DLinkListNode *cur = (DLinkListNode *)list;
        DLinkListNode *next = NULL;

        for(i=0; i<pos; i++)
            cur = cur->next;
        ret = cur->next;   //cur->next就是我们要删除的节点 
        next = ret->next;

        cur->next = next;
        if( next !=NULL)    //判断是否删除最后一个节点
        {
            if(cur == (DLinkListNode *)list)  //判断删除的是不是第一个节点
            {
                next->prev = NULL; 
            }
            else
            {
                next->prev = cur;
            }
        }

        list->length--;
    }

    return ret;
}

//main.c文件

#include <stdio.h>

#include "dlinklist.h"

int main( void )
{
    int i;
    DLinkListNode *p = NULL;
    DLinkListNode v1 = {NULL,NULL,1};
    DLinkListNode v2 = {NULL,NULL,2};
    DLinkListNode v3 = {NULL,NULL,3};
    DLinkListNode v4 = {NULL,NULL,4};
    DLinkList *list = DLinkList_Create();     //创建后返回创建好的头节点ret(指向结构体的指针)

    DLinkList_Insert(list,&v1,0);
    DLinkList_Insert(list,&v2,0);
    DLinkList_Insert(list,&v3,0);
    DLinkList_Insert(list,&v4,0);

    for(i=0; i<DLinkList_Length(list);i++)
    {
        p = DLinkList_Get(list,i);
        printf("%d ",p->item);
    }
    printf("\n");

    DLinkList_Destroy(list);
}

//Makefile


cc :=gcc -g

main : main.o dlinklist.o
    gcc $^ -o $@


.PHONY : main clean

clean:
    rm -rf *.o main
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值