头插法建立双向链表

单链表只能向后访问其他节点的数据,若需要寻找某节点前面节点的数据,则需要从表头开始,重新进行遍历,效率不高,为了克服单链表单向性的缺点,可以利用双向链表

双向链表有两个指针域,一个指向直接后继,一个指向直接前驱,头插法建立双链表的方法如下

结构体定义如下

typedef struct DuLNode{
    int data;
    struct DuLNode *prior, *next;
}DuLNode, *DuLNode;

prior代表前驱,next代表后继

初始化头节点head,前驱和后继均指向空

head->next = head->prior = NULL;

图形表示如下图

对于头插法来说,插入第一个元素和插入第一个元素后面的元素有区别,因为第一个元素不需要考虑该插入元素同后面元素的节点连接关系。

插入的节点为p

首先执行代码

head->next = p;

建立head节点与p节点的后继关系(head的后继是p,head节点的下一个是p)

图形化表示为

接着执行代码

p->prior = head;

建立head节点与p节点的前驱关系(p节点的前驱是head,p节点的前一个是head)

图形化表示为

此时就将第一个节点插入到了头节点后面,并且建立了前驱和后继的关系

下面考虑插入第二个节点的情况(第三个,第四个....节点的插入情况同第二个节点相同)

插入的节点名称是P

首先执行代码

p->next = head->next;

head->next指向的是头节点的下一个节点,由于要在头节点和头节点的下一个节点之间插入节点,所以执行该语句将节点p指向的头节点的下一个节点

接着执行

head->next->prior = p;

head->next表示的是头节点的下一个节点,将该节点的前驱定义为p,建立他们之间的前驱关系

执行完毕后图像化表示为

此时,节点P同head的下一个节点A1的前驱后继关系建立完毕,接着要建立head同p的前驱后继关系

代码为

head->next = p;
p->prior = head;

图形化表示

至此,上述操作建立了新的前驱和后继关系,实现了头节点链表的建立,完整代码如下

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

typedef struct DuLNode{
    int data;
    struct DuLNode *prior, *next;
}DuLNode, *DuLinklist;


//尾插法创建双向链表
void CreateTailList(DuLinklist *L, int n){//创建大小长度为n的链表
    DuLinklist p, r;
    (*L) = (DuLNode *)malloc(sizeof(DuLNode));
    (*L)->next = NULL;
    (*L)->prior = NULL;
    r = (*L);
    int i = 0;
    for(i = 0; i < n; i ++){
        p = (DuLNode *)malloc(sizeof(DuLNode));
        p->data = i;
        r->next = p;
        p->prior = r;
        r = p;


    }
    r->next = NULL;
}
//头插法建立双向链表
void CreteHeadList(DuLinklist *L, int n){
    DuLinklist p, r;
    (*L) = (DuLNode *)malloc(sizeof(DuLNode));
    (*L)->next = NULL;
    (*L)->prior = NULL;
    r = (*L);
    int i = 0;
    for(i = 0; i < n; i ++){
        p = (DuLNode *)malloc(sizeof(DuLNode));
        p->data = i;
        if(r->next == NULL){//插入第一个节点时与其他方法不一样
            r->next = p;
            p->prior = r;
            p->next = NULL;
        }
        else{
            p->next = r->next;
            r->next->prior = p;
            r->next = p;
            p->prior = r;
        }
    }
}
void TraverseList(DuLinklist *L){
    DuLinklist p;
    p = (*L);
    while(p->next != NULL){
        printf("%d\n", p->next->data);
        p = p->next;
    }
}
int main()
{

    DuLinklist La;
    CreteHeadList(&La, 5);
    TraverseList(&La);
    return 0;
}

 

  • 24
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值