【数据结构专题---链表01】

数据结构专题之链表

image-20210710130755511
数据结构专题

链表

链表和数组都是数据结构,用于存储和组织数据,但它们的组织方式、性质和使用场景有很大的不同。为了更好地理解链表,让我们先了解它们的定义和性质,然后通过与数组的对比来深入理解链表。

链表:

  1. 定义:链表是由节点(Node)组成的线性数据结构,每个节点都包含数据和一个指向下一个节点的引用(在双向链表中,还包含一个指向上一个节点的引用)。

  2. 性质

    • 动态大小:链表的大小是动态的,可以根据需要增长或缩小。
    • 插入和删除:在链表的中间插入或删除一个节点的时间复杂度通常是O(1),但是要找到插入或删除的位置可能需要O(n)的时间。
    • 随机访问:链表不支持随机访问,访问某个特定索引的节点需要从头节点开始,逐个节点前进,因此时间复杂度是O(n)。
    • 空间效率:由于链表的每个节点除了数据外还需要存储指向下一个(和/或上一个)节点的引用,所以它的空间效率通常低于数组。

数组:

  1. 定义:数组是一种线性数据结构,它由一组连续的内存位置组成,每个内存位置都存储一个数据元素。

  2. 性质

    • 固定大小:传统的数组在创建时大小就确定了,不能动态地增长或缩小。
    • 插入和删除:在数组的中间插入或删除一个元素需要移动其他元素,因此时间复杂度是O(n)。
    • 随机访问:数组支持O(1)的随机访问时间,因为知道了元素的索引就可以直接计算其内存地址。
    • 空间效率:数组通常比链表更加空间有效,因为它不需要额外的引用或指针。

链表与数组对比:

  1. 内存分配:数组使用连续的内存空间,而链表使用离散的内存空间。
  2. 大小:数组的大小是固定的,而链表是动态的。
  3. 插入和删除:链表在已知节点的情况下可以实现O(1)的插入和删除,而数组通常需要O(n)。
  4. 随机访问:数组提供O(1)的随机访问,而链表则需要O(n)。
  5. 空间使用:数组通常更加空间有效,但链表提供了更多的灵活性,尤其是在动态添加和删除数据时。

结论:

选择链表还是数组取决于具体的应用场景和所需的操作。如果需要频繁的随机访问,数组可能是更好的选择;如果主要操作是插入和删除,尤其是在数据结构的中间,那么链表可能更有优势。

链表的节点由什么组成?

在C语言中,链表是一种常见的数据结构。链表中的每一个元素通常被称为“节点”。一个链表节点至少包含两部分:

  1. 数据:这部分存储实际的信息或值。
  2. 指针:这部分用于存储指向上一个/下一个节点的地址。

根据指针的多少以及尾节点指向我们可以把链表分为四种:单链表,双链表,单循环链表,双循环链表

单链表

每个节点都包含数据部分和指向下一个节点的指针。因为每个节点只有一个指针指向下一个节点,所以它被称为“单”链表。

双链表

其中每个节点包含数据部分和两个指针:一个指向前一个节点,另一个指向后一个节点。因此,与单链表相比,双链表允许双向遍历,这使得从链表中的任何给定点向前或向后移动都变得更为简单。

循环链表

循环链表是链表的另一种变体。在循环链表中,链表的最后一个节点指向第一个节点,形成一个闭环。循环链表可以是单循环链表或双循环链表。

循环链表相较于非循环链表有什么特点?

循环链表与非循环链表(即普通的单链表或双链表)在结构上有一些基本的差异,这些差异导致了它们在实际应用中的特点和用途的差异。以下是循环链表相较于非循环链表的特点:

  1. 尾部连接

    • 循环链表:链表的最后一个节点指向第一个节点,形成一个闭环。
    • 非循环链表:链表的最后一个节点的指针为NULL,表示链表的结束。
  2. 遍历

    • 循环链表:从任何一个节点开始,你可以无限次地遍历整个链表,因为它没有实际的结束。
    • 非循环链表:从头到尾遍历链表时,一旦到达尾部,就会停止。
  3. 应用场景

    • 循环链表:常用于具有周期性操作的应用,例如资源共享、约瑟夫问题、操作系统中的循环任务调度等。
    • 非循环链表:广泛用于各种应用,如数据存储、栈、队列、哈希表链地址法等。
  4. 插入和删除操作

    • 循环链表:当在链表的头部或尾部插入或删除节点时,需要更新连接来保持循环性质。
    • 非循环链表:在链表的尾部插入或删除节点时,只需要处理一个指针(尾部指针)。
  5. 空间使用

    • 循环链表:与非循环链表相比,它不会有任何指针指向NULL,因此在某种意义上,它更“紧凑”。
    • 非循环链表:链表的最后一个节点的指针总是指向NULL。
  6. 复杂性

    • 循环链表:在某些操作中,例如查找链表的结束或判断链表是否为空,需要更多的考虑,因为简单地查找指向NULL的指针不再有效。
    • 非循环链表:通常更简单、更直观。

节点中的数据可以是什么?

在C语言中,链表节点中的数据可以是几乎任何类型,这取决于你的具体需求。以下是可能的数据类型和相关示例:

  1. 基本数据类型

    • 整型 (int, long, short 等)
    • 浮点型 (float, double)
    • 字符 (char)
  2. 指针

    • 指向其他数据的指针,例如字符指针 (char*) 用于字符串。
    • 指向其他类型的指针,例如其他结构体。
  3. 数组

    • 整型数组 (int arr[10])
    • 字符数组 (例如用于存储字符串)
  4. 结构体 (struct)

    • 可以定义复合的数据结构,将多个不同的数据元素组合在一起。
    struct PersonalInfo {
        char name[50];
        int age;
        float salary;
    };
    

    在这种情况下,链表节点可能看起来像这样:

    struct Node {
        struct PersonalInfo data;
        struct Node* next;
    };
    
  5. 联合 (union)

    • 用于存储不同的数据类型,但一次只能使用其中之一。
  6. 枚举 (enum)

    • 用于表示一个有限集合的值。
  7. 其他

    • 除了上面提到的基本类型和复合类型外,几乎任何其他C语言中定义的数据类型也可以用作链表节点的数据部分。

总之,链表节点中的数据部分在C语言中是非常灵活的,可以根据具体需求和应用来选择最合适的数据类型。

接下来我们会实现

1.单链表(非循环/循环)

2.双链表(非循环/循环)

3.实现freertos中管理任务的链表

在FreeRTOS中,链表被用来维护任务。这些链表中的节点包含了指向任务控制块(Task Control Block,简称TCB)的指针。这些链表和TCB结构为操作系统提供了维护任务状态、优先级等信息的能力。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值