# Single linked list

Single linked list is a kind of linked data structure. The data in the linked list is represented by nodes. Each node consists of data element and pointer to the next data element. The pointer is the address connecting each node.

Let's be clear: a single chain table is composed of many nodes. Each node is connected with a pointer, from the predecessor node to the successor node.

(the pointer here is just a virtual reference, not like the pointer in c)

The following is an example of creating a single chain table and implementing some functions. First, distribute and explain each function, and then give the complete code

## First, create a node class

It contains data elements and pointers to the next data element

class Node(object): """Create a single node class""" def __init__(self, data): self.data = data self.next = None

## Then create a class of single chain table

It contains some functions. The next functions are included in this class.

In the class of creating a single chain table, we first write an initialization function to initialize a header node

Then write a function to determine whether the linked list is empty. If it is empty, return True

class SingleLinkedList(object): """Create a single chain table""" def __init__(self): self.head = None def is_empty(self): """Judge whether the list is empty""" return self.head is None

## Create a function to get the length of a single chain table

Now, it means the node that the cur rent pointer points to. Here, it starts from the beginning node

count is the length of the linked list. When this node is not empty, the length will be increased by one, and then the node (cur) pointed to by the current pointer will move backward, that is, the next cur will be changed to cur.

def length(self): """Get the length of the linked list""" cur = self.head count = 0 while cur is not None: count += 1 cur = cur.next return count

## Add elements to the head of the list

First, we need to create a new node, and then make the pointer of this node point to the head node of the original list, and then give the title of head node to this new node, so that this new node is a new head node.

def add_fist(self, data): """Add elements to the head of the list""" node = Node(data) node.next = self.head self.head = node

## Add elements at the end of the list

This time we need to consider two situations: the list is empty and the list is not empty

When the list is empty, we can only insert this new node into the position of the head node

When the list is not empty, we need to move the pointer to the end of the list, and then insert the new node to the next position of the last node, that is, add to the end.

def add_last(self, data): """Add elements at the end of the list""" node = Node(data) if self.is_empty(): self.head = node else: cur = self.head while cur.next is not None: cur = cur.next cur.next = node

## Add elements in the specified location of the linked list

When using this function, we need to specify the location of index: element in the linked list, data: element data

I've considered four situations here: error, insertion into the head, insertion into the tail, and insertion into the middle

Error condition: when the specified index is less than zero or greater than the length of the linked list, there must be no such position, so it is judged as an error

Insert to header: when the index is 0, it is inserted at the front of the list. We have written this function above, so we can call it directly.

Insert at the end: when the index is the length of the linked list, it is inserted at the end of the linked list, so it can be called directly

Insert in the middle: This is not a special case, so you need a count to count, move the pointer to the previous position of the position index to be added, and then insert. The central idea is that the new node points to the successor node of the node cur pointed to by the original pointer, and the node cur pointed to by the pointer points to the new node.

(some people may want to ask, is there any other way to be more concise? The answer is: Yes, it's just one of them. You can also use other methods to complete this function.)

def insert_node(self, index, data): """Add element at specified location""" node = Node(data) if index < 0 or index > self.length(): return False elif index == 0: self.add_fist() elif index == self.length(): self.add_last() else: cur = self.head count = 0 while count < index - 1: cur = cur.next count += 1 node.next = cur.next cur.next = node

## Delete specified node

There are two situations: the deleted node is the head node, and the deleted node is not the head node

The deleted node is the head node: in this case, the name of the head node can be directly given to the successor node of the head node

The deleted node is not the head node: in this case, you need to move the pointer step by step and search until you find the element to be deleted. We need two nodes: the node that the pointer points to (the node that we are looking for), and its predecessor

Because cur represents the current node and pre represents its precursor node, cur points to the header node during initialization, but there is no precursor node in the header node, so it is initialized to None. Then when you move backward, you can exchange assignments.

Finally, we find the node to be deleted, which cur currently points to, so we only need to point its precursor node pre to its successor node cur.next, so we skip the middle node cur, and thus complete the deletion operation.

def remove_node(self, data): """Delete specified node""" cur = self.head # Node pointed by pointer pre = None # Pointer to the previous node if self.head == data: self.head.next = self.head else: while cur.data is not data: pre = cur cur = cur.next pre.next = cur.next

## Find whether the specified node exists

Similar to the delete operation, we only need to search backward (cur = cur.next) to find the node to be searched.

def search_node_is_exist(self, data): """Find whether the specified node exists""" cur = self.head while cur is not None: if cur.data == data: return True else: cur = cur.next return False

## Traverse and print the entire list

Continue to search backward, and print out every node found

def traversal(self): """Traverse the entire list""" cur = self.head while cur is not None: print(cur.data) cur = cur.next

## Main function to test

Call the above function

if __name__ == '__main__': lists = SingleLinkedList() lists.add_fist(2) lists.add_fist(1) lists.add_last(4) lists.insert_node(2, 3) lists.traversal() print(lists.is_empty()) print(lists.length()) lists.remove_node(4) print(lists.search_node_is_exist(3)) lists.traversal()

## Screenshot of output results

## Complete code

class Node(object): """Create a single node class""" def __init__(self, data): self.data = data self.next = None class SingleLinkedList(object): """Create a single chain table""" def __init__(self): self.head = None def is_empty(self): """Judge whether the list is empty""" return self.head is None def length(self): """Get the length of the linked list""" cur = self.head count = 0 while cur is not None: count += 1 cur = cur.next return count def add_fist(self, data): """Add elements to the head of the list""" node = Node(data) node.next = self.head self.head = node def add_last(self, data): """Add elements at the end of the list""" node = Node(data) if self.is_empty(): self.head = node else: cur = self.head while cur.next is not None: cur = cur.next cur.next = node def insert_node(self, index, data): """Add element at specified location""" node = Node(data) if index < 0 or index > self.length(): return False elif index == 0: self.add_fist() elif index == self.length(): self.add_last() else: cur = self.head count = 0 while count < index - 1: cur = cur.next count += 1 node.next = cur.next cur.next = node def remove_node(self, data): """Delete specified node""" cur = self.head # Node pointed by pointer pre = None # Pointer to the previous node if self.head == data: self.head.next = self.head else: while cur.data is not data: pre = cur cur = cur.next pre.next = cur.next def search_node_is_exist(self, data): """Find whether the specified node exists""" cur = self.head while cur is not None: if cur.data == data: return True else: cur = cur.next return False def traversal(self): """Traverse the entire list""" cur = self.head while cur is not None: print(cur.data) cur = cur.next if __name__ == '__main__': lists = SingleLinkedList() lists.add_fist(2) lists.add_fist(1) lists.add_last(4) lists.insert_node(2, 3) lists.traversal() print(lists.is_empty()) print(lists.length()) lists.remove_node(4) print(lists.search_node_is_exist(3)) lists.traversal()

The methods of the above functions are relatively simple, and we will come into contact with deeper algorithms in the future. However, as long as we learn patiently, practice by ourselves, and find some examples to practice in depth, it is not a problem at all.