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:
operation | Linked list | Sequence table |
---|---|---|
Access element | O(n) | O(1) |
Insert / delete in header | O(1) | O(n) |
Insert / delete at tail | O(n) | O(1) |
Insert / delete in the middle | O(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.