Linear table structure-linked list

A linked list, unlike an array, does not require a continuous memory space. It uses a “pointer” to concatenate a group of scattered memory blocks, as shown in the figure:

Single list

There are many types of linked lists. The simplest is a single linked list. The single linked list is the most original linked list. Its structure is shown in the figure:

There are two nodes in the single linked list that are special, the first node and the last node. . We usually call the first node as the head node and the last node as the tail node.
Among them, the head node is used to record the base address of the linked list. With it, we can traverse to get the entire linked list. The special place of the tail node is: the pointer does not point to the next node, but points to an empty address NULL, indicating that this is the last node on the linked list.
For singly linked lists, theoretically, the time complexity of inserting and deleting nodes is O (1), and the time complexity of querying nodes is O (n).

Circular list

Then there is also a circular linked list that is extended on the basis of a single linked list. The difference between a circular linked list and a single linked list is that the tail node points to the head node, so that the head and tail are connected, a bit like a snake, and can be used to solve the "Joseph ring" problem. The structure of the circular linked list is shown in the figure:

Doubly linked list

In addition, there are more common doubly-linked lists. As the name implies, the difference between a doubly-linked list and a single-linked list is that in addition to a pointer to the next node, there is also a pointer to the previous node, so that O (1) The complexity finds the previous node. It is because of this node that the doubly linked list is more efficient at inserting and deleting nodes than the singly linked list. Although we have already mentioned that the time complexity of the insertion and deletion of the singly linked list is already O (1), this is not considered but only For the insertion and deletion operations themselves, take deletion as an example. After deleting a node, you need to point the pointer of its precursor node to the next node of the deleted node. In this way, we also need to obtain its precursor node, which is obtained in the singly linked list. The time complexity of the predecessor node is O (n), so the overall time complexity of the deletion and insertion operations of the singly linked list is also O (n), but not the doubly linked list. It has a pointer to the previous node, so its insertion And deletion time complexity is the real O (1).

In addition, for an ordered linked list, the query efficiency of the doubly linked list is obviously higher than that of the single linked list, but the better time complexity is exchanged for by the worse space complexity. The doubly linked list always requires twice the space of the single linked list. But, as we said before, in Web applications, time efficiency has a higher priority, so we usually use space for time to improve performance. Java's LinkedHashMap uses a doubly linked list at the bottom.

The structure of the doubly linked list is shown in the figure:

Doubly circular linked list

The last thing we want to introduce is a doubly circular list that combines a circular list and a doubly linked list:

in fact, it connects the head and the end of the doubly linked list through pointers.

Realize singly linked list through array function simulation

Since there is no pointer in PHP, we can use the array next, current, key and other functions to realize the linked list data structure:

<?php

/**
 * 通过 PHP 数组模拟实现单链表
 */
class LinkedList
{
    private $list = [];

    // 获取链表指定位置的元素值,从0开始
    public function get($index)
    {
        $value = NULL;
        while (current($this->list)) {
            if (key($this->list) == $index) {
                $value = current($this->list);
            }
            next($this->list);
        }
        reset($this->list);
        return $value;
    }

    // 在链表指定位置插入值,默认插到链表头部
    public function add($value, $index = 0)
    {
        array_splice($this->list, $index, 0, $value);
    }

    // 从链表指定位置删除元素
    public function remove($index)
    {
        array_splice($this->list, $index, 1);
    }

    public function isEmpty()
    {
        return !next($this->list);
    }

    public function size()
    {
        return count($this->list);
    }
}

$linkedList = new LinkedList();
$linkedList->add(4);
$linkedList->add(5);
$linkedList->add(3);
print $linkedList->get(1);   # 输出5
$linkedList->add(1, 1);      # 在结点1的位置上插入1
print $linkedList->get(1);   # 输出1
$linkedList->remove(1);      # 移除结点1上的元素
print $linkedList->get(1);   # 输出5
print $linkedList->size();   # 输出3

In PHP, arrays integrate all data structures, such as arrays, lists, hash tables, maps, etc., and because PHP does not support pointers, it is impossible to implement a real linked list. For example, pointer insertion changes cannot be achieved when inserting or deleting. Element insertion and deletion can only be achieved through the array_splice function in general, and there is no way to distinguish between a one-way linked list, a two-way linked list and a circular linked list. However, the SPL library provided by the bottom layer of PHP contains an implementation of a doubly linked list: http://php.net/manual/zh/class.spldoublylinkedlist.php, interested can go and see

Guess you like

Origin www.cnblogs.com/stringarray/p/12702354.html