C语言之双向链表详解及实例代码

C语言之双向链表详解及实例代码

本文将详细讲解C语言中双向链表的实现原理及实例代码,让读者能够深入理解双向链表的基本概念和用法。

什么是双向链表?

双向链表是一种常见的数据结构,它由多个节点构成,每个节点包含两个指针,一个指向前一个节点,一个指向后一个节点,在实际应用中可以用来存储一系列元素,以股票数据为例,将每支股票的编码和名称存储在一个双向链表中,方便快捷地查找和修改。

双向链表的实现原理

在C语言中,我们可以用结构体来定义双向链表中每个节点的数据结构,如下所示:

struct Node {
    int data;
    struct Node *prev;
    struct Node *next;
};

其中,data表示节点中存储的数据,prev指针表示上一个节点的地址,next指针表示下一个节点的地址。当链表为空时,prev和next指针都指向NULL。

插入节点的操作分为两种情况:

  • 在链表头部插入节点
  • 在链表尾部插入节点

可以定义两个函数来分别实现这两种操作:

// 在链表头部插入节点
void insert_at_head(struct Node **head_ref, int new_data) {
    struct Node *new_node = (struct Node*)malloc(sizeof(struct Node));
    new_node->data = new_data;
    new_node->next = (*head_ref);
    new_node->prev = NULL;
    if ((*head_ref) != NULL) {
        (*head_ref)->prev = new_node;
    }
    (*head_ref) = new_node;
}

// 在链表尾部插入节点
void insert_at_end(struct Node **head_ref, int new_data) {
    struct Node *new_node = (struct Node*)malloc(sizeof(struct Node));
    struct Node *last = *head_ref;
    new_node->data = new_data;
    new_node->next = NULL;
    if (*head_ref == NULL) {
        new_node->prev = NULL;
        *head_ref = new_node;
        return;
    }
    while (last->next != NULL) {
        last = last->next;
    }
    last->next = new_node;
    new_node->prev = last;
    return;
}

这两个函数的实现原理都类似,主要是通过malloc函数动态分配内存用来存储新节点的数据,然后判断链表是为空,如果不为空就在头部插入新节点或在尾部插入新节点。

示例说明

下面给出两个示例说明如何使用双向链表来实现对数据的快速查找和修改。

示例1: 股票查询系统

假设我们要实现一个股票查询系统,其中需要存储大量的股票数据,每支股票包括股票代码和股票名称两个信息。我们可以利用双向链表来存储这些数据,然后按照股票代码进行快速查找和修改。实现代码如下:

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

struct Stock {
    char code[10];
    char name[100];
    struct Stock *prev;
    struct Stock *next;
};

void insert_stock(struct Stock **head_ref, char code[], char name[]) {
    struct Stock *new_node = (struct Stock*)malloc(sizeof(struct Stock));
    strcpy(new_node->code, code);
    strcpy(new_node->name, name);
    new_node->next = (*head_ref);
    new_node->prev = NULL;
    if ((*head_ref) != NULL) {
        (*head_ref)->prev = new_node;
    }
    (*head_ref) = new_node;
}

void search_stock(struct Stock **head_ref, char code[]) {
    struct Stock *temp = *head_ref;
    while (temp != NULL) {
        if (strcmp(temp->code, code) == 0) {
            printf("股票代码:%s\n股票名称:%s\n", temp->code, temp->name);
            return;
        }
        temp = temp->next;
    }
    printf("未查找到该股票,请重新输入股票代码!\n");
}

void modify_stock(struct Stock **head_ref, char code[], char name[]) {
    struct Stock *temp = *head_ref;
    while (temp != NULL) {
        if (strcmp(temp->code, code) == 0) {
            strcpy(temp->name, name);
            printf("股票信息修改成功!\n");
            return;
        }
        temp = temp->next;
    }
    printf("未查找到该股票,请重新输入股票代码!\n");
}

int main() {
    struct Stock *head = NULL;
    insert_stock(&head, "000001", "平安银行");
    insert_stock(&head, "000002", "万科A");
    insert_stock(&head, "600036", "招商银行");
    insert_stock(&head, "600519", "贵州茅台");
    insert_stock(&head, "601318", "中国平安");
    char code[10]; char name[100];
    printf("请输入要查询的股票代码:");
    scanf("%s", code);
    search_stock(&head, code);
    printf("请输入要修改的股票代码和股票名称:");
    scanf("%s%s", code, name);
    modify_stock(&head, code, name);
    return 0;
}

示例2: 学生信息管理系统

双向链表还可以用来实现学生信息管理系统,在学生信息管理系统中,我们需要将每个学生的信息存储在一个链表中,然后实现对学生信息的更新、删除和查询等操作。实现代码如下:

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

struct Student {
    char name[20];
    int age;
    int id;
    struct Student *prev;
    struct Student *next;
};

void insert_student(struct Student **head_ref, char name[], int age, int id) {
    struct Student *new_node = (struct Student*)malloc(sizeof(struct Student));
    strcpy(new_node->name, name);
    new_node->age = age;
    new_node->id = id;
    new_node->next = (*head_ref);
    new_node->prev = NULL;
    if ((*head_ref) != NULL) {
        (*head_ref)->prev = new_node;
    }
    (*head_ref) = new_node;
}

void search_student(struct Student **head_ref, int id) {
    struct Student *temp = *head_ref;
    while (temp != NULL) {
        if (temp->id == id) {
            printf("学生姓名:%s\n学生年龄:%d\n学生ID:%d\n", temp->name, temp->age, temp->id);
            return;
        }
        temp = temp->next;
    }
    printf("未查找到该学生,请重新输入学生ID!\n");
}

void delete_student(struct Student **head_ref, int id) {
    struct Student *temp = *head_ref;
    while (temp != NULL) {
        if (temp->id == id) {
            if (temp->prev == NULL) {
                *head_ref = temp->next;
                (*head_ref)->prev = NULL;
                free(temp);
                printf("学生信息删除成功!\n");
                return;
            }
            if (temp->next == NULL) {
                temp->prev->next = NULL;
                free(temp);
                printf("学生信息删除成功!\n");
                return;
            }
            temp->prev->next = temp->next;
            temp->next->prev = temp->prev;
            free(temp);
            printf("学生信息删除成功!\n");
            return;
        }
        temp = temp->next;
    }
    printf("未查找到该学生,请重新输入学生ID!\n");
}

int main() {
    struct Student *head = NULL;
    insert_student(&head, "Tom", 18, 1001);
    insert_student(&head, "Jerry", 20, 1002);
    insert_student(&head, "Lucy", 19, 1003);
    insert_student(&head, "Amy", 18, 1004);
    int option, id, age; char name[20];
    while (1) {
        printf("---------------------------\n");
        printf("1.查询学生信息\n2.删除学生信息\n3.退出\n");
        printf("---------------------------\n");
        printf("请选择要执行的操作:");
        scanf("%d", &option);
        switch(option) {
            case 1:
                printf("请输入要查询的学生ID:");
                scanf("%d", &id);
                search_student(&head, id);
                break;
            case 2:
                printf("请输入要删除的学生ID:");
                scanf("%d", &id);
                delete_student(&head, id);
                break;
            case 3:
                printf("退出系统成功!\n");
                return 0;
            default:
                printf("输入错误,请重新输入!\n");
        }
    }
    return 0;
}

总结

本文详细讲解了C语言中双向链表的实现原理及其应用,同时给出了两个实际示例,希望读者通过学习本文,掌握C语言中链表的基本使用方法,加深对链表的理解,有助于提高C语言程序的编写能力。

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

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

相关文章

  • 利用C语言实现顺序表的实例操作

    利用C语言实现顺序表的实例操作 什么是顺序表 顺序表,是指用一段地址连续的存储单元依次存储线性表中的各元素,从而形成的线性表。在顺序表中,元素的存储位置是按其逻辑顺序存放的。顺序表的优点是数据存储密度高,支持随机存取和直接访问,缺点是插入和删除操作效率较低。 顺序表的基本操作 顺序表的基本操作包括: 初始化顺序表 插入元素 删除元素 查找元素 修改元素 打印…

    C 2023年5月23日
    00
  • tc编译的dos程序和vc编译的win32控制台程序的异同

    让我来详细讲解一下“tc编译的dos程序和vc编译的win32控制台程序的异同”。 1. 什么是TC和VC编译器 TC编译器是Turbo C Compiler的简称,是Borland公司开发的一款DOS下的C语言集成开发环境,主要用于编写DOS程序。 VC编译器是Microsoft Visual C++ Compiler的简称,是Microsoft公司开发的…

    C 2023年5月23日
    00
  • win10蓝屏0xc0000001安全模式进不了怎么办?win10出现0xc0000001的解决方法

    win10蓝屏0xc0000001安全模式进不了的解决方法 如果你在使用win10时,突然遇到了蓝屏问题,并且提示0xc0000001错误代码,那么该怎么办呢?事实上,很多用户在此遇到问题时感到很困惑,接下来,我们将为大家详细讲解win10蓝屏0xc0000001安全模式进不了的解决方法,帮助大家轻松摆脱此问题。 方法一:通过修复启动 修复启动是一种通用的解…

    C 2023年5月23日
    00
  • c# 使用Json.NET实现json序列化

    C# 使用Json.NET实现json序列化 Json.NET是一个第三方的C#库,它可以帮助我们在C#中实现json序列化和反序列化,广泛应用于Web应用程序和移动应用程序的开发中。本文将详细介绍如何使用Json.NET实现json序列化。 步骤1:添加Json.NET库引用 首先,我们需要在C#项目中添加Json.NET库引用。可以通过在Visual S…

    C 2023年5月23日
    00
  • 关于Fragment already added问题的解决方案

    关于 Fragment already added 问题的解决方案一般有以下几种: 方案一:使用findFragmentByTag 在Activity中使用FragmentManager的findFragmentByTag()方法来查找Fragment是否已经被添加。如果已经添加,则不需要重复添加,避免出现Fragment already added异常。 …

    C 2023年5月23日
    00
  • 关于VS+QT5应用程序换图标的解决方案

    关于VS+QT5应用程序换图标的解决方案,可以如下操作: 1. 原理介绍 QT5程序在编译后的exe文件的图标,并不是我们常见的.ico格式,而是.qrc格式。.qrc格式是QT资源文件的格式,里面包含了程序中需要用到的图像、音频等资源。所以,如果我们想要修改QT程序的图标,实际上就是需要修改资源文件中的图标。 2. 修改.res文件 (1)在项目中添加一个…

    C 2023年5月23日
    00
  • JSON字符串和对象相互转换实例分析

    下面就为您详细讲解“JSON字符串和对象相互转换实例分析”的完整攻略。 什么是JSON字符串和对象? JSON(JavaScript Object Notation)是一个轻量级的数据交换格式。它基于JavaScript的一个子集。JSON格式具有自我描述性,易于理解和阅读。同时也易于解析和生成,这使JSON成为数据交换和存储的常用格式。 JSON字符串 J…

    C 2023年5月23日
    00
  • VSCode搭建C/C++编译环境的详细教程

    让我们来详细讲解一下“VSCode搭建C/C++编译环境的详细教程”,具体步骤如下: 1. 安装VSCode 下载并安装Visual Studio Code: https://code.visualstudio.com/ 2. 安装C/C++插件 在VSCode中点击菜单栏的“扩展”(Extensions)按钮,在搜索框中输入“C/C++”,找到官方提供的插…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部