数据结构 双链表 c语言

双向链表

单链表,通过这样的链式存储,我们不用像顺序表一样一次性申请一段连续的空间,而是只需要单独为结点申请内存空间,同时在插入和删除的速度上也比顺序表轻松。不过有一个问题是,如果我们想要操作某一个结点,比如删除或是插入,那么由于单链表的性质,我们只能先去找到它的前驱结点,才能进行。

为了解决这种查找前驱结点非常麻烦的问题,我们可以让结点不仅保存指向后续结点的指针

这样我们无论哪个结点,都能快速的找到对应的前驱结点,就很方便了,这样的链表我们称为双向链表

初始化

将node->next 和 node->prev置空

插入函数

加if判断优化

完成先序逆序遍历链表

逆序先打印 后开始赋值

删除操作

代码如下

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

typedef int E;

struct
NodeList{
   
E element;
    struct
NodeList * next;
    struct
NodeList * prev;
};

typedef struct
NodeList * nodelist;

//初始化函数
void initList(nodelist node){
    node->
next = node->prev = NULL;
}
//添加函数
int addList(nodelist node, int element, int index){
   
if(index < 1) return 0;
    while
(--index){
        node = node->
next;
        if
(node == NULL) return 0;
   
}
   
nodelist  newNode = malloc(sizeof (struct NodeList));
    if
(newNode == NULL) return 0;
   
//此时存在两种情况,一种是后继结点不存在的情况,一种是后继结点存在的情况,为了优化代码需要进行if判断
   
if(node->next){
       
//node->next存在 即后继结点存在
       
newNode->next = node->next; //将新插入结点的下一指向 指向所查找出来的前驱结点的下一指向
       
node->next->prev = newNode; //将前驱结点指向的下一结点的上一指向 指向新插入的结点
   
}else{
       
//若后继结点不存在
       
newNode->next = NULL; //将新插入的结点的下一个指向置为空
   
}
    node->
next = newNode;//将头结点的下一指向 指向新插入的结点
   
newNode->prev = node;//将新插入结点的上一指向 指向头结点
   
newNode->element = element;
    return
1;
}
//以先序的顺序 查找函数
int searchList(nodelist node, int element){
   
int index = 1;
    if
(node->next == NULL) return 0;
    while
(node){
        node = node->
next;
        if
(node->element == element) return index;
       
index ++;
   
}
}

//删除函数
int deleteList(nodelist node, int element){
   
int index = searchList(node,element);
    while
(--index){
        node = node->
next;
        if
(node == NULL) return 0;
   
}
   
//若要删除的结点不存在
   
if(node->next == NULL) return 0;
   
//找到待删除的结点 以便释放内存
   
nodelist temp = node->next;
   
//考虑删除结点下一个存不存在
   
if(node->next->next){
        node->
next = node->next->next;
       
node->next->next->prev = node;
   
}else{
        node->
next = NULL;
   
}
   
//释放内存
   
free(temp);
    return
1;
}
int main(){
   
struct NodeList node;
   
initList(&node);
    for
(int i = 1; i <= 5; i++){
        addList(&node
, i*i+i, i);
   
}
   
//先正向遍历
   
nodelist thisNode = &node;
    while
(thisNode->next){
        thisNode = thisNode->
next;
       
printf("%d ",thisNode->element);
   
}
    printf(
"\n");
   
//后逆向遍历
   
while(thisNode->prev){
        printf(
"%d ",thisNode->element);
       
thisNode = thisNode->prev;
   
}
    printf(
"\n%d",searchList(&node,6));
   
deleteList(&node, 6);
   
printf("\n");
    while
(thisNode->next){
        thisNode = thisNode->
next;
       
printf("%d ",thisNode->element);
   
}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值