C语言学习之链表的实现详解

yizhihongxing

下面我将详细讲解“C语言学习之链表的实现详解”的完整攻略。

1. 链表的定义

链表是一种数据结构,它由一系列节点组成。每个节点由一个数据部分和一个指向下一个节点的地址部分组成。链表可以有多种形式,例如单向链表、双向链表、循环链表等。

2. 链表的实现

2.1. 单向链表

单向链表是最简单的链表形式,一个节点只包含一个指向下一个节点的指针。在C语言中,我们可以使用结构体来表示一个节点,如下所示:

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

链表的头指针指向第一个节点的地址,如果为空链表则指向 NULL。可以定义如下:

struct Node* head = NULL;

可以通过遍历链表找到某个节点,如下所示:

struct Node* p = head;
while(p != NULL && p->data != target){
    p = p->next;
}

其它操作,例如插入节点、删除节点等,也比较容易实现。

2.2. 双向链表

双向链表是一种带有前向指针和后向指针的链表结构。每个节点都有一个指向前驱节点的指针和一个指向后继节点的指针。定义如下:

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

可以通过前向、后向指针轻松在双向链表上进行遍历和操作。

2.3. 循环链表

循环链表是一种特殊的链表,最后一个节点的后继指针指向第一个节点。定义与单向链表和双向链表类似,只是需要注意循环链接的实现。

3. 示例说明

下面我们看两个示例,分别是单向链表和双向链表的实现。

3.1. 单向链表示例

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

/*定义节点类型*/
struct Node{
    int data;
    struct Node* next;
};

/*头插法插入节点*/
void insertAtHead(struct Node** headRef, int data){
    /*创建节点*/
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    new_node->data = data;
    /*将新节点插入链表头部*/
    new_node->next = (*headRef);
    (*headRef) = new_node;
}

/*尾插法插入节点*/
void insertAtTail(struct Node** headRef, int data){
    /*创建节点*/
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    new_node->data = data;
    new_node->next = NULL;

    if((*headRef) == NULL){
        (*headRef) = new_node;
        return;
    }

    struct Node* p = (*headRef);
    while(p->next != NULL){
        p = p->next;
    }
    p->next = new_node;
}

/*删除节点*/
void deleteNode(struct Node** headRef, int target){
    /*如果要删除的节点是头节点*/
    if((*headRef) != NULL && (*headRef)->data == target){
        (*headRef) = (*headRef)->next;
        return;
    }

    struct Node* p = (*headRef);
    struct Node* prev = NULL;
    while(p != NULL && p->data != target){
        prev = p;
        p = p->next;
    }
    /*如果找到目标节点*/
    if(p != NULL){
        prev->next = p->next;
        free(p);
    }
}

/*打印链表*/
void printList(struct Node* head){
    struct Node* p = head;
    while(p != NULL){
        printf("%d ", p->data);
        p = p->next;
    }
}

int main(){
    struct Node* head = NULL;

    insertAtHead(&head, 2);
    insertAtHead(&head, 1);
    insertAtTail(&head, 3);
    insertAtTail(&head, 4);

    printList(head);

    deleteNode(&head, 3);
    deleteNode(&head, 1);

    printList(head);

    return 0;
}

3.2. 双向链表示例

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

/*定义节点类型*/
struct DNode{
    int data;
    struct DNode* prev;
    struct DNode* next;
};

/*头插法插入节点*/
void insertAtHead(struct DNode** headRef, int data){
    /*创建节点*/
    struct DNode* new_node = (struct DNode*)malloc(sizeof(struct DNode));
    new_node->data = data;

    /*插入链表头*/
    new_node->prev = NULL;
    new_node->next = (*headRef);
    if((*headRef) != NULL){
        (*headRef)->prev = new_node;
    }
    (*headRef) = new_node;
}

/*尾插法插入节点*/
void insertAtTail(struct DNode** headRef, int data){
    /*创建节点*/
    struct DNode* new_node = (struct DNode*)malloc(sizeof(struct DNode));
    new_node->data = data;
    new_node->next = NULL;

    if((*headRef) == NULL){
        new_node->prev = NULL;
        (*headRef) = new_node;
        return;
    }

    struct DNode* p = (*headRef);
    while(p->next != NULL){
        p = p->next;
    }
    new_node->prev = p;
    p->next = new_node;
}

/*删除节点*/
void deleteNode(struct DNode** headRef, int target){
    struct DNode* p = (*headRef);
    while(p != NULL && p->data != target){
        p = p->next;
    }
    /*如果要删除的节点是头节点*/
    if(p != NULL && p == (*headRef)){
        (*headRef) = p->next;
        if((*headRef) != NULL){
            (*headRef)->prev = NULL;
        }
        free(p);
        return;
    }
    /*如果找到目标节点*/
    if(p != NULL){
        p->prev->next = p->next;
        if(p->next != NULL){
            p->next->prev = p->prev;
        }
        free(p);
    }
}

/*打印链表(正序)*/
void printList(struct DNode* head){
    struct DNode* p = head;
    while(p != NULL){
        printf("%d ", p->data);
        p = p->next;
    }
}

/*打印链表(反序)*/
void printListReverse(struct DNode* head){
    struct DNode* p = head;
    while(p != NULL && p->next != NULL){
        p = p->next;
    }
    while(p != NULL){
        printf("%d ", p->data);
        p = p->prev;
    }
}

int main(){
    struct DNode* head = NULL;

    insertAtHead(&head, 2);
    insertAtHead(&head, 1);
    insertAtTail(&head, 3);
    insertAtTail(&head, 4);

    printList(head);
    printf("\n");
    printListReverse(head);

    deleteNode(&head, 3);
    deleteNode(&head, 1);

    printf("\n");
    printList(head);

    return 0;
}

以上就是链表的实现攻略和两个示例的说明,希望对你有所帮助。

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

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

相关文章

  • C++超详细讲解单链表的实现

    首先我们来了解一下单链表的概念。 单链表是一种常见的数据结构,在计算机科学中被广泛使用。它是由节点所组成的数据结构,其中每个节点都包含两部分,一个是存储数据的元素,另一个是指向下一个节点的指针。单链表的首节点被称为头部,而最后一个节点则被称为尾部。单链表可以通过在头部插入和删除元素来实现高效地数据操作。接下来我们将讲解如何实现一个 C++ 版的单链表。 实现…

    数据结构 2023年5月17日
    00
  • C++高级数据结构之优先队列

    C++高级数据结构之优先队列 什么是优先队列? 优先队列是一种特殊的队列,其中每个元素都有一个优先级。当加入一个元素时,它会被放置在队列中的适当位置,以确保优先级最高的元素位于队头。从队列中取出元素时,总是从队头删除元素。 优先队列的应用 优先队列的常见应用场景包括: 操作系统任务调度 网络传输协议TCP中的拥塞控制算法 各种图像算法如边缘检测等 C++中S…

    数据结构 2023年5月17日
    00
  • Java数据结构之顺序表篇

    Java数据结构之顺序表篇 什么是顺序表 顺序表是由一组地址连续、大小相等的存储单元依次存储数据元素的线性表。 顺序表的表示 Java语言中,可以使用数组来表示顺序表。 public class SeqList<T> { private Object[] element;// 定义数组存储数据元素 private int length;// 当前…

    数据结构 2023年5月17日
    00
  • C++实现LeetCode(211.添加和查找单词-数据结构设计)

    首先,我们需要先了解一下题目的要求和限制,以及具体的解题思路。 题目描述 设计一个支持添加、删除、查找单词的数据结构。添加和删除单词的操作需要支持普通词和通配符’.’。查找单词只支持普通词,不支持通配符’.’。所有单词都是非空的。 解题思路 这道题可以使用前缀树(Trie树)来实现。 首先,我们需要定义一个单词类,它包含两个字段:单词字符串和单词长度。然后,…

    数据结构 2023年5月17日
    00
  • JavaScript中数据结构与算法(四):串(BF)

    JavaScript中数据结构与算法(四):串(BF) 一、串的定义 在计算机科学中,串(string)是由零个或多个字符组成的有限序列。零个字符的串称为空串(empty string),也叫做空格串(null string)。串中的字符数称为串的长度(length)。 二、串BF算法的定义 串的BF算法,也称为朴素算法(Brute-Force Algori…

    数据结构 2023年5月17日
    00
  • 【ACM算法竞赛日常训练】DAY3题解与分析【旅游】【tokitsukaze and Soldier】

    DAY3共2题: 旅游 tokitsukaze and Soldier ? 作者:Eriktse? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)?? 原文链接(阅读原文获得更好阅读体验): 旅游 题目传送门:https://ac.nowcoder…

    算法与数据结构 2023年4月18日
    00
  • C++LeetCode数据结构基础详解

    C++LeetCode数据结构基础详解攻略 什么是LeetCode? LeetCode是一个专门为程序员提供的算法题平台。平台上汇集了各种算法、数据结构和编程题,用户可以在平台上挑战各种难度的算法用来提高自己的编程能力和算法素养。 如何学习LeetCode? 学习LeetCode的关键是掌握数据结构和算法。下面介绍如何结合具体的C++代码来学习LeetCod…

    数据结构 2023年5月17日
    00
  • nginx内存池源码解析

    Nginx内存池源码解析 Nginx是一个高性能、高并发的Web服务器。为了提高其性能和速度,Nginx采用了特殊的内存管理机制,即内存池。 什么是内存池? 内存池是一种高效的内存分配和管理机制。它将一块内存划分成多个大小相等的块,并按需分配给系统。当内存块不再使用时,它并不被立即释放,而是留在内存池中待重复利用。 Nginx内存池结构 Nginx内存池主要…

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