一起来看看C语言线性表的线性链表

一起来看看C语言线性表的线性链表攻略

线性链表概述

线性链表是线性表的一种实现方式,它通过每个节点中包含指向下一个节点的指针来实现表中元素之间的链接,可以动态地增加、删除节点。线性链表分为带头节点的链表和不带头节点的链表,其中带头节点的链表更为常见。

实现思路

结构体定义

我们可以定义一个结构体来表示每个节点,例如:

typedef struct ListNode {
    int data;               // 节点数据
    struct ListNode *next;  // 指向下一个节点的指针
} ListNode;

初始化

初始化链表需要创建头节点,具体步骤如下:

  1. 使用malloc函数动态分配一个ListNode类型的结构体空间p;
  2. 将头指针head指向p;
  3. 将p的next指针赋值为NULL;
  4. 释放p。

示例代码:

void InitList(ListNode **head) {
    *head = (ListNode *)malloc(sizeof(ListNode));  // 申请头节点空间
    (*head)->next = NULL;                          // 头节点指针域为空
}

插入节点

插入节点分为头插法和尾插法。头插法就是将新节点插入到链表的头部,尾插法就是将新节点插入到链表的尾部。

头插法

  1. 使用malloc函数动态分配一个ListNode类型的结构体空间p;
  2. 将新节点的数据存入p的data成员中;
  3. 将p的next指针指向头节点的next指针所指向的节点;
  4. 将头节点的next指针指向p。

示例代码:

void InsertHead(ListNode *head, int data) {
    ListNode *p = (ListNode *)malloc(sizeof(ListNode));  // 申请新节点空间
    p->data = data;                                      // 存储数据
    p->next = head->next;                                // p指向第一个节点
    head->next = p;                                      // 变更头节点的指向
}

尾插法

  1. 使用malloc函数动态分配一个ListNode类型的结构体空间p;
  2. 将新节点的数据存入p的data成员中;
  3. 将原链表的最后一个节点的next指针指向p;
  4. 将p的next指针指向NULL,表示链表结束。

示例代码:

void InsertTail(ListNode *head, int data) {
    ListNode *p = (ListNode *)malloc(sizeof(ListNode));  // 申请新节点空间
    p->data = data;                                      // 存储数据
    p->next = NULL;                                      // 新节点指向NULL
    ListNode *q = head;
    while (q->next != NULL) {
        q = q->next;                                    // 移动q指针到链表末尾
    }
    q->next = p;                                        // 链接新节点
}

删除节点

删除节点需要找到要删除的节点的前驱节点,具体步骤如下:

  1. 如果链表中不存在节点,则直接返回;
  2. 从头节点开始遍历链表;
  3. 找到要删除节点的前驱节点;
  4. 将前驱节点指向要删除节点的后继节点;
  5. 释放要删除的节点。

示例代码:

void DeleteNode(ListNode *head, int data) {
    ListNode *p = head->next;
    ListNode *q = head;
    while (p != NULL && p->data != data) {
        q = p;          // 保留上一个节点
        p = p->next;    // 移动p指针查找节点data
    }
    if (p == NULL) {
        return;         // 不存在节点data
    }
    q->next = p->next;  // 上一个节点指向下一个节点
    free(p);            // 释放要删除的节点
}

打印链表

遍历链表,将每个节点的值打印出来即可。

示例代码:

void PrintList(ListNode *head) {
    ListNode *p = head->next;
    while (p != NULL) {
        printf("%d ", p->data); // 打印节点值
        p = p->next;            // 移动p指针
    }
    printf("\n");
}

销毁链表

遍历链表,依次释放每个节点的空间即可。

示例代码:

void DestroyList(ListNode *head) {
    ListNode *p = head;
    while (p != NULL) {
        ListNode *q = p;
        p = p->next;
        free(q);
    }
}

示例说明

示例一:使用头插法构建链表

ListNode *head;
InitList(&head);
InsertHead(head, 1);
InsertHead(head, 2);
InsertHead(head, 3);
PrintList(head);        // 输出:3 2 1

示例二:使用尾插法构建链表

ListNode *head;
InitList(&head);
InsertTail(head, 1);
InsertTail(head, 2);
InsertTail(head, 3);
PrintList(head);        // 输出:1 2 3

总结

线性链表是一种常见的数据结构,有助于我们理解数据结构的相关知识。在实现时,我们需要定义结构体、实现初始化、插入、删除、遍历、销毁操作等。在实际应用中,可以根据具体业务场景来选择使用带头节点的链表或不带头节点的链表实现。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一起来看看C语言线性表的线性链表 - Python技术站

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

相关文章

  • C语言数据结构 双向链表的建立与基本操作

    C语言数据结构 双向链表的建立与基本操作 双向链表的定义 双向链表是一种常见的线性数据结构,它由多个结点组成,每个结点有两个指针,一个指向前一个结点,一个指向后一个结点。对于一个双向链表,我们可以获得其第一个结点和最后一个结点的指针,也可以沿着链表从前往后或从后往前遍历链表的每个结点。 双向链表的建立 我们首先需要定义一个双向链表的结点类型,包括两个指针,一…

    数据结构 2023年5月17日
    00
  • C语言数据结构之堆排序的优化算法

    C语言数据结构之堆排序的优化算法攻略 堆排序简介 堆排序(HeapSort)是一种树形选择排序,在排序过程中始终保持一个最大堆,每次将堆顶元素与最后一个元素交换位置,并进行一次最大堆调整操作,直到整个序列有序为止。 堆排序的时间复杂度为O(nlogn),具有不需额外存储空间的特点,因此广泛应用于内存受限的场景。 堆排序的优化算法 1. 建堆操作的优化 将序列…

    数据结构 2023年5月17日
    00
  • [paper reading]|IC-FPS: Instance-Centroid Faster Point Sampling Module for 3D Point-base

    摘要: 本文说首次实现了大规模点云场景中基于点的模型的实时检测(<30ms); 首先指出FPS采样策略进行下采样是耗时的,尤其当点云增加的时候,计算量和推理时间快速增加; 本文提出IC-FPS;包含两个模块:local feature diffusion based background point filter (LFDBF);Centroid In…

    算法与数据结构 2023年4月17日
    00
  • Java红黑树的数据结构与算法解析

    Java红黑树的数据结构与算法解析 红黑树简介 红黑树是一种平衡二叉搜索树,其中的每个节点上都有一个黑色或红色的标记,并且满足以下性质: 根节点是黑色的; 叶子节点是黑色的空节点(NULL); 如果一个节点是红色的,则其子节点必须是黑色的; 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点; 新插入的节点默认是红色的。 具体来说,只有在删除或者某…

    数据结构 2023年5月17日
    00
  • 浅谈iOS 数据结构之链表

    浅谈iOS 数据结构之链表 在计算机科学中,链表是一种数据结构,用于存储一系列按顺序排列的元素。链表的一个关键点是它不需要连续的内存空间来存储元素,相反,每个元素由一个指向下一个元素的指针组成。在iOS开发中,链表在各种场景下都有所应用,如UITableView和UICollectionView的数据源等。本文将详细讲解链表的基本知识和使用技巧。 链表的基本…

    数据结构 2023年5月17日
    00
  • JavaScript中的Map数据结构详解

    JavaScript中的Map数据结构详解 什么是Map数据结构 Map是JavaScript中一种新的数据结构,类似于对象,但是比对象更加灵活。Map可以将任意类型的值作为键名(包括对象、字符串、数字、布尔值等),并且不会将键名强制转换为字符串。Map的键值对个数没有限制,可以根据需要动态地增加或者删除键值对。Map内部实现了一个哈希表,因此增加、删除、查…

    数据结构 2023年5月17日
    00
  • 比特币区块链的数据结构

    让我来为你详细讲解比特币区块链的数据结构。 1. 区块链的定义 比特币区块链是一个去中心化的、可追溯的、公共的、可验证的交易数据库。每一笔交易都通过哈希算法,与之前的交易连接成一个区块,形成了一个数据结构链,也就是“区块链”。 2. 区块链的数据结构 区块链的数据结构由区块、交易和哈希三部分组成: 区块 区块是区块链数据结构的基本单位,每一个区块代表着一段时…

    数据结构 2023年5月17日
    00
  • C语言数据结构与算法时间空间复杂度基础实践

    C语言数据结构与算法时间空间复杂度基础实践攻略 基本概念 时间复杂度:算法在执行时所需要的基本操作数,通常用O(n)表示,其中n是输入数据的规模。时间复杂度越小,算法执行所需要的时间越少,算法效率越高。 空间复杂度:算法在执行时所需要的额外空间数,通常用O(S)表示,其中S是额外的空间数。空间复杂度越小,所需的额外空间越少,算法的内存效率越高。 实践步骤 1…

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