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

下面我将详细讲解“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语言植物大战数据结构的快速排序可以分为以下步骤: 准备工作 首先需要定义一个关于植物大战中植物的结构体,例如: struct Plant { int hp; int atk; int cost; }; 然后准备一个装载植物信息的数组: struct Plant plants[] = { {75, 36, 100}, {100, 20, 50}, {125,…

    数据结构 2023年5月17日
    00
  • C语言数据结构二叉树简单应用

    C语言数据结构二叉树简单应用攻略 1. 什么是二叉树? 二叉树(Binary Tree)是一种树形结构,它的每个节点最多包含两个子节点,它是非线性数据结构,可以用来表示许多问题,例如家族关系、计算机文件系统等等。 2. 二叉树的基本操作 二叉树的基本操作包括插入、删除、查找等等,本攻略主要讲解插入和查找的实现。 插入操作的代码如下: // 二叉树的插入操作 …

    数据结构 2023年5月17日
    00
  • C语言线性表全面梳理操作方法

    C语言线性表全面梳理操作方法 线性表概述 线性表是一种常用的数据结构,是指数据元素之间存在一定逻辑顺序,每个元素都有唯一的前驱和后继。 线性表有两种存储方式: 顺序存储结构 和 链式存储结构。 顺序存储结构 顺序存储结构是指采用顺序存储方式存储线性表,即将线性表的元素依次存储在一段连续的存储空间内。 代码示例:创建顺序存储线性表 #define MaxSiz…

    数据结构 2023年5月17日
    00
  • php数据结构与算法(PHP描述) 查找与二分法查找

    以下是详细讲解“php数据结构与算法(PHP描述) 查找与二分法查找”的完整攻略。 1. 数据结构与算法简介 数据结构是计算机中存储和组织数据的方式。它涉及到数据的表示、处理和存储方式等。 算法则是完成特定任务的步骤集合。算法设计可以优化计算机程序的效率和速度。 PHP是一种非常流行的服务器端脚本语言,数据结构和算法对web开发者来说非常重要。因此,我们需要…

    数据结构 2023年5月17日
    00
  • Java数据结构之对象比较详解

    Java数据结构之对象比较详解 在Java中,比较两个对象的内容是否相等一直是程序员们比较困惑的问题。本文将详细探讨Java中对象比较的几种方式,并给出相应的示例。 基本类型比较 在Java中,比较基本类型的值可以使用双等号(==)进行判断。例如: int a = 1; int b = 1; boolean result = a == b; System.o…

    数据结构 2023年5月17日
    00
  • 栈(Stack)

    概述 栈就是一种 只允许在表尾进行插入和删除操作 的 线性表 栈的特点 先进后出 ,在表尾进行插入和删除操作 数组实现栈 crown crown:使用bottom来确定栈顶所在数组的下标,默认为 -1 空栈 当空栈时 ,crown = -1 栈是否为空 当 crown = -1 时 ,栈为空 ,不能 遍历 ,出栈 , 获取栈顶元素 栈是否已满 当 crown…

    算法与数据结构 2023年4月19日
    00
  • Java数据结构之堆(优先队列)详解

    Java数据结构之堆(优先队列)详解 概述 堆是一种基于树的数据结构,它可以用来解决很多问题,例如排序、优先队列等。在堆中,每个节点的值都小于或等于它的子节点的值。堆分为两种类型:最大堆和最小堆。在最大堆中,根节点的值最大;而在最小堆中,根节点的值最小。 堆的操作主要有以下两种: 插入:将一个元素插入到堆中,需要维护堆的性质,即节点的值小于或等于子节点的值。…

    数据结构 2023年5月17日
    00
  • Python实现的数据结构与算法之基本搜索详解

    Python实现的数据结构与算法之基本搜索详解 在计算机科学中,搜索指的是在一组数据中找到目标数据的过程。搜索算法是解决各种问题的关键,即使是拼图游戏和图像识别也要依赖搜索算法。本文将介绍基本的搜索算法,包括线性/顺序搜索、二分搜索和广度优先搜索。 线性/顺序搜索 顺序搜索又称为线性搜索,它遍历整个数据集以查找特定元素。顺序搜索可以用于查找未排序的列表。该算…

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