freeCodeCamp/guide/chinese/miscellaneous/data-structure-linked-list/index.md

9.5 KiB
Raw Blame History

title localeTitle
Data Structure Linked List 数据结构链表

就像用花朵制作的花环一样,链表由节点组成。我们称这个特殊花环上的每朵花都是一个节点。并且每个节点指向该列表中的下一个节点以及它具有数据(这里是花的类型)。

类型

  1. 单链表

单链表包含具有data字段和next字段的节点,该字段指向序列中的下一个节点。可以在单链表上执行的操作是插入,删除和遍历。

`

Singly Link List 

   head 
    | 
    | 
  +-----+--+      +-----+--+      +-----+------+ 
  |  1  |o----->  |  2  |o----->  |  3  | NULL | 
  +-----+--+      +-----+--+      +-----+------+ 

`

应用

CPython的内部实现框架和评估变量保存在堆栈中。

为此我们需要迭代前向aur得到头部因此单独使用链表。

  1. 双重链表

双向链表包含具有data字段的节点, next字段和指向序列中前一节点的另一个链接字段prev

`

双重链表


          head 
           | 
           | 
  +------+-----+--+    +--+-----+--+       +-----+------+ 
  |      |     |o------>  |     |o------>  |     |      | 
  | NULL |  1  |          |  2  |          |  3  | NULL | 
  |      |     |  <------o|     |  <------o|     |      | 
  +------+-----+--+    +--+-----+--+       +-----+------+ 

`

应用

浏览器缓存允许您点击BACK和FORWARD按钮。在这里我们需要维护一个双向链表 URLs作为数据字段以允许双向访问。要转到上一个URL我们将使用prev字段,并转到下一页,我们将使用next字段。

  1. 循环链表

循环链表是单链表,其中最后一个节点, next字段指向序列中的第一个节点。

`

循环链表


     head 
      | 
      | 
    +-----+--+      +-----+--+      +-----+--+ 

- > | 1 | o -----> | 2 | o -----> | 3 | o ----
| + ----- + - + + ----- + - + + ----- + - + |
| |


`

应用

分时问题由操作系统解决。

在分时环境中操作系统必须维护当前用户的列表并且必须允许每个用户一次使用一小部分CPU时间一个用户。操作系统将选择一个用户让他/她使用少量的CPU时间然后转到下一个用户。

对于这个应用程序应该没有NULL指针除非绝对没有人请求CPU时间即列表为空。

基本操作

  1. 插入

要向列表中添加新元素。

`

插入开头


  • 使用给定数据创建新节点。
  • 将新节点指向旧head next
  • head到这个新的节点。

插入中间/结尾


在节点X之后插入。

  • 使用给定数据创建新节点。
  • 指向新节点的next老X的next
  • 点X在此新节点next
    `

时间复杂度O1

  1. 删除

从列表中删除现有元素。

`

删除开头


  • 获取head指向的节点为Temp。
  • head到温度的next
  • Temp节点使用的可用内存。

在中间/结尾删除


节点X后删除。

  • 获取X指向的节点为Temp。
  • 点X next着Temp的next
  • Temp节点使用的可用内存。
    `

时间复杂度O1

  1. 遍历

穿越列表。

`

穿越


  • 获取head指向的节点为Current。
  • 检查Current是否为空并显示它。
  • 点电流为当前的next ,并移动到上面的步骤。
    `

时间复杂度On//这里n是链接列表的大小

履行

单链表的C ++实现

// Header files 
 #include <iostream> 
 
 struct node 
 { 
    int data; 
    struct node *next; 
 }; 
 
 // Head pointer always points to first element of the linked list 
 struct node *head = NULL; 

在每个节点中打印数据

// Display the list 
 void printList() 
 { 
    struct node *ptr = head; 
 
    // Start from the beginning 
 while(ptr != NULL) 
 { 
    std::cout << ptr->data << " "; 
    ptr = ptr->next; 
 } 
 
 std::cout << std::endl; 
 } 

插入开头

// Insert link at the beginning 
 void insertFirst(int data) 
 { 
    // Create a new node 
    struct node *new_node = new struct node; 
 
    new_node->data = data; 
 
 // Point it to old head 
 new_node->next = head; 
 
 // Point head to new node 
 head = new_node; 
 
 std::cout << "Inserted successfully" << std::endl; 
 } 

删除开头

// Delete first item 
 void deleteFirst() 
 { 
    // Save reference to head 
    struct node *temp = head; 
 
    // Point head to head's next 
 head = head->next; 
 
 // Free memory used by temp 
 temp = NULL: 
 delete temp; 
 
 std::cout << "Deleted successfully" << std::endl; 
 } 

尺寸

// Find no. of nodes in link list 
 void size() 
 { 
    int length = 0; 
    struct node *current; 
 
    for(current = head; current != NULL; current = current->next) 
 { 
    length++; 
 } 
 
 std::cout << "Size of Linked List is " << length << std::endl; 
 } 

搜索

// Find node with given data 
 void find(int data){ 
 
    // Start from the head 
 struct node* current = head; 
 
 // If list is empty 
 if(head == NULL) 
 { 
    std::cout << "List is empty" << std::endl; 
    return; 
 } 
 
 // Traverse through list 
 while(current->data != data){ 
 
    // If it is last node 
    if(current->next == NULL){ 
        std::cout << "Not Found" << std::endl; 
        return; 
    } 
    else{ 
        // Go to next node 
        current = current->next; 
    } 
 } 
 
 // If data found 
 std::cout << "Found" << std::endl; 
 } 

节点后删除

// Delete a node with given data 
 void del(int data){ 
 
    // Start from the first node 
 struct node* current = head; 
 struct node* previous = NULL; 
 
 // If list is empty 
 if(head == NULL){ 
    std::cout << "List is empty" << std::endl; 
    return ; 
 } 
 
 // Navigate through list 
 while(current->data != data){ 
 
    // If it is last node 
    if(current->next == NULL){ 
        std::cout << "Element not found" << std::endl; 
        return ; 
    } 
    else { 
        // Store reference to current node 
        previous = current; 
        // Move to next node 
        current = current->next; 
    } 
 
 } 
 
 // Found a match, update the node 
 if(current == head) { 
    // Change head to point to next node 
    head = head->next; 
 } 
 else { 
    // Skip the current node 
    previous->next = current->next; 
 } 
 
 // Free space used by deleted node 
 current = NULL; 
 delete current; 
 std::cout << "Deleted succesfully" << std::endl; 
 } 

:rocket: 运行代码

单链表的Python实现

class Node(object): 
    # Constructor 
    def __init__(self, data=None, next=None): 
        self.data = data 
        self.next = next 
 
    # Function to get data 
 def get_data(self): 
    return self.data 
 
 # Function to get next node 
 def get_next(self): 
    return self.next 
 
 # Function to set next field 
 def set_next(self, new_next): 
    self.next = new_next 
 class LinkedList(object): 
    def __init__(self, head=None): 
        self.head = head 

插入

    # Function to insert data 
 def insert(self, data): 
    # new_node is a object of class Node 
    new_node = Node(data) 
    new_node.set_next(self.head) 
    self.head = new_node 
    print("Node with data " + str(data) + " is created succesfully") 

尺寸

    # Function to get size 
 def size(self): 
    current = self.head 
    count = 0 
    while current: 
        count += 1 
        current = current.get_next() 
    print("Size of link list is " + str(count)) 

搜索

    # Function to search a data 
 def search(self, data): 
    current = self.head 
    found = False 
    while current and found is False: 
        if current.get_data() == data: 
            found = True 
        else: 
            current = current.get_next() 
    if current is None: 
        print("Node with data " + str(data) + " is not present") 
    else: 
        print("Node with data " + str(data) + " is found") 

节点后删除

    # Function to delete a node with data 
 def delete(self, data): 
    current = self.head 
    previous = None 
    found = False 
    while current and found is False: 
        if current.get_data() == data: 
            found = True 
        else: 
            previous = current 
            current = current.get_next() 
    if current is None: 
        print("Node with data " + str(data) + " is not in list") 
    elif previous is None: 
        self.head = current.get_next() 
        print("Node with data " + str(data) + " is deleted successfully") 
    else: 
        previous.set_next(current.get_next()) 
        print("Node with data " + str(data) + " is deleted successfully") 

:rocket: 运行代码

好处

  1. 链表是一种动态数据结构,可以在程序运行时增长和收缩,分配和释放内存。
  2. 节点的插入和删除很容易在任何位置的链表中实现。

缺点

  1. 由于指针使用的内存( nextprev ),它们使用的内存比数组多。
  2. 链表中无法随机访问。我们必须按顺序访问节点。
  3. 它比数组更复杂。如果一种语言自动支持数组绑定检查Arrays会更好地为您服务。

注意

我们必须在C中使用free并在C ++中删除以释放已删除节点使用的空间而在Python和Java中可用垃圾收集器自动收集空间。