Data structure and algorithm III [single linked list]

Keywords: Algorithm data structure linked list

1. Linked list

The construction of sequence table needs to know the data size in advance to apply for continuous storage space, and the data needs to be relocated during expansion, so it is not very flexible to use.
Linked list structure can make full use of computer memory space and realize flexible dynamic memory management.

1.1 definition of linked list

Linked list is a common basic data structure. It is a linear table, but it does not store data continuously like a sequential table. Instead, it stores the location information (i.e. address) of the next node in each node (data storage unit).

2. One way linked list

One way linked list, also known as single linked list, is the simplest form of linked list. Each node of it contains two fields, an information field (element field) and a link field. This link points to the next node in the linked list, and the link field of the last node points to a null value.

(1) The table element field elem is used to store specific data.
(2) The link domain next is used to store the location of the next node (the identity in python).
(3) The variable p points to the position of the head node (head node) of the linked list. Any node in the list can be found from P.

Define nodes and single linked lists as classes respectively:

2.1 implementation of nodes

class SingleNode(object):
    """Node of single linked list"""
    def __init__(self,item):
        # item stores data elements
        self.item = item
        # Next stores the ID of the next node
        self.next = None

2.2 operation of single linked list

(1)is_empty() whether the linked list is empty
(2) length() linked list length
(3) travel() traverses the entire linked list
(4) add(item) adds an element to the header of the linked list
(5) append(item) adds an element at the end of the linked list
(6) insert(pos, item) adds an element at the specified location
(7) remove(item) deletes a node
(8) search(item) finds whether the node exists

2.3 implementation of single linked list

class SingleLinkList(object):
    """Single linked list"""
    def __init__(self):
        self._head = None

    def is_empty(self):
        """Determine whether the linked list is empty"""
        return self._head == None

    def length(self):
        """Linked list length"""
        # cur initially refers to the head node
        cur = self._head
        count = 0
        # The tail node points to None. When the tail is not reached
        while cur != None:
            count += 1
            # Move cur back one node
            cur = cur.next
        return count

    def travel(self):
        """Traversal linked list"""
        cur = self._head
        while cur != None:
            print cur.item,
            cur = cur.next
        print ""

Add element to header

def add(self, item):
        """Add element to header"""
        # First create a node to save the item value
        node = SingleNode(item)
        # Point the link domain next of the new node to the header node, that is_ Where head points
        node.next = self._head
        # The head of the linked list_ Head points to the new node
        self._head = node

Add element to tail

def append(self, item):
        """Add element to tail"""
        node = SingleNode(item)
        # First judge whether the linked list is empty. If it is empty, the_ head points to the new node
        if self.is_empty():
            self._head = node
        # If it is not empty, find the tail and point the next of the tail node to the new node
        else:
            cur = self._head
            while cur.next != None:
                cur = cur.next
            cur.next = node

Add element at specified location

def insert(self, pos, item):
        """Add element at specified location"""
        # If the specified position pos is before the first element, header insertion is performed
        if pos <= 0:
            self.add(item)
        # If the specified position exceeds the tail of the linked list, the tail insertion is performed
        elif pos > (self.length()-1):
            self.append(item)
        # The specified location was found
        else:
            node = SingleNode(item)
            count = 0
            # pre is used to point to the previous position pos-1 of the specified position POS, and initially move from the original node to the specified position
            pre = self._head
            while count < (pos-1):
                count += 1
                pre = pre.next
            # First point the next of the new node to the node at the insertion location
            node.next = pre.next
            # Point the next of the previous node at the insertion location to the new node
            pre.next = node

Delete node

def remove(self,item):
        """Delete node"""
        cur = self._head
        pre = None
        while cur != None:
            # The specified element was found
            if cur.item == item:
                # If the first is the deleted node
                if not pre:
                    # Point the header pointer to the next node of the header node
                    self._head = cur.next
                else:
                    # Point the next node before the deletion location to the next node after the deletion location
                    pre.next = cur.next
                break
            else:
                # Continue to move the node backward according to the linked list
                pre = cur
                cur = cur.next

Find whether the node exists

def search(self,item):
        """The linked list looks up whether the node exists and returns True perhaps False"""
        cur = self._head
        while cur != None:
            if cur.item == item:
                return True
            cur = cur.next
        return False

test

if __name__ == "__main__":
    ll = SingleLinkList()
    ll.add(1)
    ll.add(2)
    ll.append(3)
    ll.insert(2, 4)
    print "length:",ll.length()
    ll.travel()
    print ll.search(3)
    print ll.search(5)
    ll.remove(1)
    print "length:",ll.length()
    ll.travel()

2.4 comparison between linked list and sequential list

The linked list loses the advantage of random reading of sequential list. At the same time, due to the increase of node pointer field, the space overhead of the linked list is relatively large, but the use of storage space should be relatively flexible.

The operation complexity of linked list and sequential list is as follows:

operationLinked listSequence table
Access elementO(n)O(1)
Insert / delete in headerO(1)O(n)
Insert / delete at tailO(n)O(1)
Insert / delete in the middleO(n)O(n)

Note that although the surface complexity is O(n), the linked list and sequential list perform completely different operations during insertion and deletion. The main time-consuming operation of linked list is traversal search, and the complexity of deletion and insertion is O(1). Sequential table lookup is very fast, and the main time-consuming operation is copy overwrite. Except for the special case where the target element is at the tail, all elements after the operation point need to be shifted back and forth during insertion and deletion of the sequence table, which can only be done by copying and overwriting.

Posted by arkleyjoe on Mon, 01 Nov 2021 10:34:40 -0700