原文: https://www.programiz.com/dsa/linked-list

在本教程中,您将学习链表及其应用。 您还将学习如何在链表上创建和执行不同的操作。

在寻宝游戏中,您首先要寻找第一个线索。 当您找到它时,它不再具有宝藏,而是具有下一条线索的位置,依此类推。 您会一直遵循这些线索,直到找到宝藏为止。

链表类似。 它是一系列连接的“节点”,包含下一个节点的“地址”。 每个节点可以存储一个数据点,该数据点可以是数字,字符串或任何其他类型的数据。


链表表示

链表 - 图1

链表表示

您必须从某个地方开始,所以我们给第一个节点的地址一个特殊的名称,叫做HEAD

另外,由于链表的下一个节点指向NULL,因此可以确定链表中的最后一个节点。


如何引用下一个节点?

涉及一些指针魔术。 让我们考虑一下每个节点包含的内容:

  • 数据项
  • 另一个节点的地址

我们将数据项和下一个节点引用都包装在一个结构中,如下所示:

  1. struct node
  2. {
  3. int data;
  4. struct node *next;
  5. };

了解链表节点的结构是掌握链表节点的关键。

每个结构节点都有一个数据项和一个指向另一个结构节点的指针。 让我们创建一个包含三个项目的简单链表,以了解其工作原理。

  1. /* Initialize nodes */
  2. struct node *head;
  3. struct node *one = NULL;
  4. struct node *two = NULL;
  5. struct node *three = NULL;
  6. /* Allocate memory */
  7. one = malloc(sizeof(struct node));
  8. two = malloc(sizeof(struct node));
  9. three = malloc(sizeof(struct node));
  10. /* Assign data values */
  11. one->data = 1;
  12. two->data = 2;
  13. three->data=3;
  14. /* Connect nodes */
  15. one->next = two;
  16. two->next = three;
  17. three->next = NULL;
  18. /* Save address of first node in head */
  19. head = one;

如果您不懂上述任何几行,则只需要对指针和结构进行复习。

仅需几个步骤,我们就创建了一个包含三个节点的简单链表。

链表 - 图2

具有三个节点的简单链表

链表的功能来自断开链并重新加入链的能力。 例如。 如果您想将元素 4 放在 1 和 2 之间,则步骤为:

  • 创建一个新的struct node并为其分配内存。
  • 将其数据值添加为 4
  • 将其下一个指针指向包含 2 作为数据值的struct node
  • 将下一个指针更改为我们刚刚创建的节点“1”。

在数组中执行类似的操作将需要移动所有后续元素的位置。

在 python 和 Java 中,可以使用下面的代码所示的类来实现链表。


链表工具

列表是最流行和最有效的数据结构之一,可以在每种编程语言(例如 C,C++ ,Python,Java 和 C# )中实现。

除此之外,链表是学习指针如何工作的好方法。 通过练习如何操作链表,您可以准备学习更高级的数据结构,例如图形和树。


Python,Java 和 C/C++ 示例

  1. # Linked list implementation in Python
  2. class Node:
  3. # Creating a node
  4. def __init__(self, item):
  5. self.item = item
  6. self.next = None
  7. class LinkedList:
  8. def __init__(self):
  9. self.head = None
  10. if __name__ == '__main__':
  11. linked_list = LinkedList()
  12. # Assign item values
  13. linked_list.head = Node(1)
  14. second = Node(2)
  15. third = Node(3)
  16. # Connect nodes
  17. linked_list.head.next = second
  18. second.next = third
  19. # Print the linked list item
  20. while linked_list.head != None:
  21. print(linked_list.head.item, end=" ")
  22. linked_list.head = linked_list.head.next
  1. // Linked list implementation in Java
  2. class LinkedList {
  3. // Creating a node
  4. Node head;
  5. static class Node {
  6. int value;
  7. Node next;
  8. Node(int d) {
  9. value = d;
  10. next = null;
  11. }
  12. }
  13. public static void main(String[] args) {
  14. LinkedList linkedList = new LinkedList();
  15. // Assign value values
  16. linkedList.head = new Node(1);
  17. Node second = new Node(2);
  18. Node third = new Node(3);
  19. // Connect nodess
  20. linkedList.head.next = second;
  21. second.next = third;
  22. // printing node-value
  23. while (linkedList.head != null) {
  24. System.out.print(linkedList.head.value + " ");
  25. linkedList.head = linkedList.head.next;
  26. }
  27. }
  28. }
  1. // Linked list implementation in C
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. // Creating a node
  5. struct node {
  6. int value;
  7. struct node *next;
  8. };
  9. // print the linked list value
  10. void printLinkedlist(struct node *p) {
  11. while (p != NULL) {
  12. printf("%d ", p->value);
  13. p = p->next;
  14. }
  15. }
  16. int main() {
  17. // Initialize nodes
  18. struct node *head;
  19. struct node *one = NULL;
  20. struct node *two = NULL;
  21. struct node *three = NULL;
  22. // Allocate memory
  23. one = malloc(sizeof(struct node));
  24. two = malloc(sizeof(struct node));
  25. three = malloc(sizeof(struct node));
  26. // Assign value values
  27. one->value = 1;
  28. two->value = 2;
  29. three->value = 3;
  30. // Connect nodes
  31. one->next = two;
  32. two->next = three;
  33. three->next = NULL;
  34. // printing node-value
  35. head = one;
  36. printLinkedlist(head);
  37. }
  1. // Linked list implementation in C++
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. // Creating a node
  5. class Node {
  6. public:
  7. int value;
  8. Node* next;
  9. };
  10. int main() {
  11. Node* head;
  12. Node* one = NULL;
  13. Node* two = NULL;
  14. Node* three = NULL;
  15. // allocate 3 nodes in the heap
  16. one = new Node();
  17. two = new Node();
  18. three = new Node();
  19. // Assign value values
  20. one->value = 1;
  21. two->value = 2;
  22. three->value = 3;
  23. // Connect nodes
  24. one->next = two;
  25. two->next = three;
  26. three->next = NULL;
  27. // print the linked list value
  28. head = one;
  29. while (head != NULL) {
  30. printf("%d ", head->value);
  31. head = head->next;
  32. }
  33. }

链表复杂度

时间复杂度

最坏情况 平均情况
搜索 O(n) O(n)
插入 O(1) O(1)
删除 O(1) O(1)

空间复杂度:O(n)


链表应用

  • 动态内存分配
  • 实现栈和队列
  • 软件中的撤消功能
  • 哈希表,图