C语言线性表之双链表详解

C语言线性表之双链表详解

前言

本教程将详细介绍C语言中双链表的实现方法以及相关操作,适合有一定C语言基础的读者。

双链表定义

双链表是一种常见的数据结构,与单链表不同,双链表中每个节点不仅有指向后续节点的指针,还有指向前续节点的指针,即“双向链表”。

双链表的节点结构体可以定义如下:

typedef struct double_node{
    int data;
    struct double_node *prev;
    struct double_node *next;
}DoubleNode;

其中,data表示节点中存储的数据,prev指向前续节点,next指向后续节点。

双链表操作

初始化双链表

在使用双链表前,需要先初始化一个空表头。代码如下:

DoubleNode* init_double_list(){
    DoubleNode* head=(DoubleNode*)malloc(sizeof(DoubleNode));
    head->next=NULL;
    head->prev=NULL;
    return head;
}

在双链表中插入节点

有两种在双链表中插入节点的方法:在表头插入节点和在表尾插入节点。

1.在表头插入节点

在双链表表头插入节点的代码如下:

void insert_head(DoubleNode* list,int data){
    DoubleNode* new_node=(DoubleNode*)malloc(sizeof(DoubleNode));
    new_node->data=data;
    new_node->next=list->next;
    new_node->prev=list;
    list->next=new_node;
    if(new_node->next!=NULL){
        new_node->next->prev=new_node;
    }
}

2.在表尾插入节点

在双链表表尾插入节点的代码如下:

void insert_tail(DoubleNode* list,int data){
    DoubleNode* new_node=(DoubleNode*)malloc(sizeof(DoubleNode));
    new_node->data=data;
    new_node->prev=NULL;
    new_node->next=list;
    while(list->next!=NULL){
        list=list->next;
    }
    list->next=new_node;
    new_node->prev=list;
}

在双链表中删除节点

有两种在双链表中删除节点的方法:删除表头节点和删除表尾节点。

1.删除表头节点

在双链表表头删除节点的代码如下:

void delete_head(DoubleNode* list){
    if(list->next!=NULL){
        DoubleNode* temp=list->next;
        list->next=temp->next;
        if(temp->next!=NULL){
            temp->next->prev=list;
        }
        free(temp);
    }
}

2.删除表尾节点

在双链表表尾删除节点的代码如下:

void delete_tail(DoubleNode* list){
    if(list->next!=NULL){
        while(list->next->next!=NULL){
            list=list->next;
        }
        DoubleNode* temp=list->next;
        list->next=NULL;
        free(temp);
    }
}

示例

示例1

以下代码演示了双链表的初始化、在表头插入节点和在表尾插入节点操作:

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

typedef struct double_node{
    int data;
    struct double_node *prev;
    struct double_node *next;
}DoubleNode;

DoubleNode* init_double_list(){
    DoubleNode* head=(DoubleNode*)malloc(sizeof(DoubleNode));
    head->next=NULL;
    head->prev=NULL;
    return head;
}

void insert_head(DoubleNode* list,int data){
    DoubleNode* new_node=(DoubleNode*)malloc(sizeof(DoubleNode));
    new_node->data=data;
    new_node->next=list->next;
    new_node->prev=list;
    list->next=new_node;
    if(new_node->next!=NULL){
        new_node->next->prev=new_node;
    }
}

void insert_tail(DoubleNode* list,int data){
    DoubleNode* new_node=(DoubleNode*)malloc(sizeof(DoubleNode));
    new_node->data=data;
    new_node->prev=NULL;
    new_node->next=list;
    while(list->next!=NULL){
        list=list->next;
    }
    list->next=new_node;
    new_node->prev=list;
}

void print_double_list(DoubleNode* list){
    while(list->next!=NULL){
        printf("%d->",list->next->data);
        list=list->next;
    }
    printf("NULL\n");
}

int main(){
    DoubleNode* list=init_double_list();
    insert_head(list,1);
    insert_head(list,2);
    insert_head(list,3);
    insert_tail(list,4);
    insert_tail(list,5);
    insert_tail(list,6);
    print_double_list(list);
    return 0;
}

输出结果如下:

3->2->1->4->5->6->NULL

示例2

以下代码演示了双链表的在表头删除节点和在表尾删除节点操作:

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

typedef struct double_node{
    int data;
    struct double_node *prev;
    struct double_node *next;
}DoubleNode;

DoubleNode* init_double_list(){
    DoubleNode* head=(DoubleNode*)malloc(sizeof(DoubleNode));
    head->next=NULL;
    head->prev=NULL;
    return head;
}

void insert_head(DoubleNode* list,int data){
    DoubleNode* new_node=(DoubleNode*)malloc(sizeof(DoubleNode));
    new_node->data=data;
    new_node->next=list->next;
    new_node->prev=list;
    list->next=new_node;
    if(new_node->next!=NULL){
        new_node->next->prev=new_node;
    }
}

void insert_tail(DoubleNode* list,int data){
    DoubleNode* new_node=(DoubleNode*)malloc(sizeof(DoubleNode));
    new_node->data=data;
    new_node->prev=NULL;
    new_node->next=list;
    while(list->next!=NULL){
        list=list->next;
    }
    list->next=new_node;
    new_node->prev=list;
}

void delete_head(DoubleNode* list){
    if(list->next!=NULL){
        DoubleNode* temp=list->next;
        list->next=temp->next;
        if(temp->next!=NULL){
            temp->next->prev=list;
        }
        free(temp);
    }
}

void delete_tail(DoubleNode* list){
    if(list->next!=NULL){
        while(list->next->next!=NULL){
            list=list->next;
        }
        DoubleNode* temp=list->next;
        list->next=NULL;
        free(temp);
    }
}

void print_double_list(DoubleNode* list){
    while(list->next!=NULL){
        printf("%d->",list->next->data);
        list=list->next;
    }
    printf("NULL\n");
}

int main(){
    DoubleNode* list=init_double_list();
    insert_head(list,1);
    insert_head(list,2);
    insert_head(list,3);
    insert_tail(list,4);
    insert_tail(list,5);
    insert_tail(list,6);
    print_double_list(list);
    delete_head(list);
    delete_tail(list);
    print_double_list(list);
    return 0;
}

输出结果如下:

3->2->1->4->5->6->NULL
2->1->4->5->NULL

结论

本教程详细介绍了双链表的定义以及相关操作,包括初始化、插入节点、删除节点等。通过示例演示可以更好地理解双链表的相关操作。如果读者已经掌握并理解了本教程的内容,可以尝试在实际项目中应用了解到的知识。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言线性表之双链表详解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • C语言数据结构 栈的基础操作

    C语言数据结构 栈的基础操作 1. 栈的基本概念 栈(Stack)是一种基于LIFO(后进先出)原理的数据结构,类似于一组盘子,只能在盘子的顶部进行操作。每次从顶部添加或移除盘子。 栈具有两个基本操作:入栈(push)和出栈(pop)。当添加一个元素时,我们称其为“push”,当移除一个元素时,我们称其为“pop”。 2. 栈的实现 栈可以使用数组或链表来实…

    数据结构 2023年5月17日
    00
  • Java常见数据结构面试题(带答案)

    Java常见数据结构面试题(带答案)完整攻略 介绍 在Java面试中,数据结构不可避免地成为一部分的考察内容。因此,掌握Java常见数据结构,对于提高面试成功率十分必要。本篇攻略将会介绍常见的Java数据结构,并提供相应的面试题目和答案,希望可以帮助面试者在面试当中更好地展示自己的实力。 目录 结构体 数组 链表 栈 队列 树 哈希表 结构体 在Java中并…

    数据结构 2023年5月17日
    00
  • 字符串算法–$\mathcal{KMP,Trie}$树

    \(\mathcal{KMP算法}\) 实际上,完全没必要从\(S\)的每一个字符开始,暴力穷举每一种情况,\(Knuth、Morris\)和\(Pratt\)对该算法进行了改进,称为 \(KMP\) 算法。 而\(KMP\)的精髓在于,对于每次失配之后,我都不会从头重新开始枚举,而是根据我已经得知的数据,从某个特定的位置开始匹配;而对于模式串的每一位,都有…

    算法与数据结构 2023年4月18日
    00
  • java中的PriorityQueue类过程详解

    Java中的PriorityQueue类过程详解 Java中的PriorityQueue类是一个基于优先级堆的无界优先级队列,它以小顶堆的形式来维护队列。在Java Collections Framework中,它实现了Queue接口,因此可以使用Queue的所有方法。 PriorityQueue类的基本性质 元素按照优先级排序:PriorityQueue类…

    数据结构 2023年5月17日
    00
  • Java数据结构之插入排序与希尔排序

    Java数据结构之插入排序与希尔排序 插入排序 插入排序是一种简单而有效的排序算法。它的基本思想是将一个元素插入已经排好序的部分中。插入排序的过程可以用以下伪代码表示: for i=1 to length-1 j = i while j > 0 and array[j-1] > array[j] swap array[j] and array[j…

    数据结构 2023年5月17日
    00
  • C语言实现带头结点的链表的创建、查找、插入、删除操作

    C语言实现带头结点的链表的创建、查找、插入、删除操作攻略 一、链表基本概念 链表是一种动态的数据结构,它可以在运行时动态地分配内存,支持数据的插入、删除等操作。链表(Linked List)由多个节点(Node)组成,每个节点包含两部分,一个是数据部分(Data),另一个是指向下一个节点的指针(Next)。 二、带头结点的链表 带头结点的链表是一种特殊的链表…

    数据结构 2023年5月17日
    00
  • Java数据结构之链表的增删查改详解

    Java数据结构之链表的增删查改详解 简介 链表是非常常用的数据结构之一,它将数据储存在一个个结点中,每个结点存储了它所代表的数据和它下一个结点的指针,通过这些指针链接在一起,形成了一条链。 新建链表 // 定义链表中元素的结构 class ListNode { int val; ListNode next; ListNode(int x) { val = …

    数据结构 2023年5月17日
    00
  • C语言近万字为你讲透树与二叉树

    C语言近万字为你讲透树与二叉树 什么是树? 树是一种用来组织数据的非线性数据结构,它由一个根节点和若干个子节点组成,并且每个节点可能有若干个子节点。 什么是二叉树? 二叉树是一种特殊的树,它的每个节点最多只有两个子节点,并且分别称为左子节点和右子节点,左子节点在二叉树中永远排在右子节点的前面。 二叉树的遍历方式 二叉树的遍历方式有三种: 前序遍历(preor…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部