双向链表的实现(c语言)

什么是双向链表

     双向链表同单链表一样,都属于链表。但双向链表属于复杂型的链表,在双向链表中,每一个节点都存在前驱,后继和数据。而双向链表的出现则是为了解决算法频繁的寻找前驱节点,如果就单链表来说,每次寻找前驱节点都要重新遍历一遍链表的话,会影响真个程序的执行效率,增加了算法的时间复杂度。双链表的前驱就完美的解决了这个问题。

双向链表的定义

双链表的节点定义主要包括前驱和后继还有指针域,如图所示:
在这里插入图片描述

而节点的结构定义为:

typedef struct line{
    ElemType data;
    struct line *pre;//指向前驱节点
    struct line *next;//指向后继节点
}Line,*LinkList;

双向链表的尾插法

    双向链表的尾插法和单链表的尾插法实现感觉差别不大,也就多了一个前驱节点,但总的来说代码的核心部分还是同样的实现。

LinkList  DoubleLinkList_T(){
    Line *line,*L;
    line=(Line*) malloc(sizeof (Line));
    line->pre=NULL;
    line->next=NULL;
    L=line;
    int x;
    while (scanf("%d",&x)!=EOF){
        Line *node;
        node= (Line*)malloc(sizeof(Line));
            node->data=x;
            node->next=L->next;
            L->next= node;
            node->pre=L;
            L=node;//往后移一步
    }
    return line;
}

双向链表的插入

  双向链表在插入数据的过程,如图所示:

在这里插入图片描述

status DoubleLinkList_Insert(LinkList L,int i,ElemType e){
    Line *Node,*p,*r;
    Node=L;
    int j=1;
    while (j<i){
        Node=Node->next;
        j++;
    }
    p=Node->next;//L的后进
    r=(Line*) malloc(sizeof(Line));
    if(r==NULL){
        printf("分配内存失败");
        return ERROR;
    }
    r->data=e;
    r->next=Node->next;
    Node->next=r;
    r->pre=p->pre;
    p->pre=r;
    return OK;
}

对于插入操作最核心的的也就是为下面这4步:

    r->next=Node->next;//新节点指向
    Node->next=r;
    r->pre=p->pre;
    p->pre=r;//向前

  第一步就是先连接上要成为后继的节点。过后就修改原来节点的后继指向,让其指向新创建的节点,这也就是第二步。这2步完成之后第三步也就需要修改后继的pre了,只有这样才能连上。最后也要将新创立的节点的pre连接上之前的节点,也就是第4个步骤。

双向链表的删除

双向链表的删除,就是要直接遍历整个链表得到删除节点的位置,再通过其前驱和后继完成对指针的删除操作。

status DoubleLinkList_Delete(LinkList L,ElemType e){
    Line *Node,*p,*r;
    Node=L;
    //通过传入得到数据进行对比找到对应的节点
    while (Node->data!=e){
        Node=Node->next;
    }
    //通过修改其前驱和后继让需要删除的节点脱离
    p=Node->next;
    r=Node->pre;
    p->pre=Node->pre;
    r->next=Node->next;
    //释放目标节点
    free(Node);
    return OK;
}

完整代码

#include "stdlib.h"
#include "stdio.h"
#define OK 1
#define ERROR 0
typedef int status;
typedef int ElemType;
typedef struct line{
    ElemType data;
    struct line *pre;
    struct line *next;
}Line,*LinkList;

LinkList  DoubleLinkList_T(){
    Line* line,*L;
    line=(Line*) malloc(sizeof (Line));
    line->pre=NULL;
    line->next=NULL;

    L=line;
    int x;
    while (scanf("%d",&x)!=EOF){
        Line *node;
        node= (Line*)malloc(sizeof(Line));
            node->data=x;
            node->next=L->next;
            L->next= node;
            node->pre=L;
            L=node;
    }
    return line;
}
void PrintList(LinkList list){
    list=list->next;
    while ( list){
        printf("%d  ",list->data);
        list=list->next;
    }
}

status DoubleLinkList_Insert(LinkList L,int i,ElemType e){
    Line *Node,*p,*r;
    Node=L;
    int j=1;
    while (j<i){
        Node=Node->next;
        j++;
    }
    p=Node->next;//L的后进
    r=(Line*) malloc(sizeof(Line));
    if(r==NULL){
        printf("分配内存失败");
        return ERROR;
    }
    r->data=e;
    r->next=Node->next;
    Node->next=r;
    r->pre=p->pre;
    p->pre=r;
    return OK;
}
status DoubleLinkList_Delete(LinkList L,ElemType e){
    Line *Node,*p,*r;
    Node=L;
    while (Node->data!=e){
        Node=Node->next;
    }
    p=Node->next;
    r=Node->pre;
    p->pre=Node->pre;
    r->next=Node->next;
    free(Node);
    return OK;
}
int main(){
    Line *line=DoubleLinkList_T();
    printf("初始的链表:");
    PrintList(line);
    printf("\n");
    DoubleLinkList_Insert(line,3,7);
    printf("插入的链表:");
    PrintList(line);
    DoubleLinkList_Delete(line,3);
    printf("\n");
    printf("删除后的链表:");
    PrintList(line);
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值