[data structure] - single chain table, use Python to create a simple single chain table (very detailed explanation)

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.  

Published 12 original articles, won praise 14, visited 4366
Private letter follow

Tags: less

Posted on Mon, 10 Feb 2020 01:14:09 -0500 by Maverickb7