--Python achieve a new name and a one-way circular list doubly linked list

Foreword

Chicken dish college students to record and share their own learning process, not talking about new technology, beg you mouth mercy !
Earlier we talked about how to realize the Python a single linked list data structure in this case there is no down pointers, object-oriented programming very brilliant ah, implemented by a node type, there can be settled in series to form a point list. Since we are all linked lists, doubly linked list and then the one-way circular list with a one-way linked list is not father and son relationship thing! Then we can use inheritance to implement doubly linked list and a one-way circular linked list, making a lot of code which can be reused to improve the efficiency of writing code. Here I will introduce to focus on other members of the family Python list of unique method of implementation.

Doubly linked list

What is doubly linked list? Refers to a doubly linked list each node has two links: a pointer to the previous node, when this node is the first node, point None; and the other pointing to the next node, when this node is the last node, point none. Probably manifestation follows is a doubly linked list of Fig.
Here Insert Picture Description
In fact, doubly linked list is to have links to the first point on the basis of a single node on the list, so that information when we visited node before quickly find a node.

Doubly linked list node to achieve

Compared to a single chain added a new point to the first node of a "pointer" (link).

class Node(object):
    """双向链表节点"""
    def __init__(self, item):
        self.item = item
        self.next = None
        self.prev = None

Doubly linked list of operations

  • is_empty () list is empty
  • length () chain length
  • travel () traverse the list
  • search (item) to find whether there is a node
  • add (item) head the list add
  • append (item) list the tail added
  • insert (pos, item) Add specified position
  • remove (item) to delete node
    analysis down can be found, sentenced to air operations doubly linked list, calculate chain length of the operation, traversing operation, the search operation with a single list of code is the same, here we can use the inherited method to make doubly linked list to inherit single chain class codes.
class DoubleLinkList(SingleLinkList):
    """双链表"""
    pass

Two-way linked list

add (item) head the list add

Add a doubly linked list head element with a single list lacks distinction, it is to the original point to the first element of the newly added element.

    def add(self, item):
        """链表头部添加元素,头插法"""
        node = Node(item)
        node.next = self.__head
        self.__head = node
        node.next.prev = node

append (item) list the tail added

First consider the general case, the tail of a doubly linked list to add a single list with the same, you only need to add a link pointing to the front, if the list is empty, pointing directly to the head node to node newly added.

    def append(self, item):
        """链表尾部添加元素, 尾插法"""
        node = Node(item)
        if self.is_empty():
            self.__head = node
        else:
            cur = self.__head
            while cur.next != None:
                cur = cur.next
            cur.next = node
            node.prev = cur

insert (pos, item) Add specified position

Here Insert Picture Description
The original link to open, and then relink properly link the steps above, node.next = cur, node.prev = cur.prev, cur.prev.next = node, cur.prev = node. It should be noted that the while loop exit condition here is count <pos instead of a single linked list count <pos-1, because I can move the cursor directly to the cur at the pos position, without the need to stop before a lived, because the previous node prev points. The other operation of the single list of special cases.

    def insert(self, pos, item):
        """指定位置添加元素
        :param  pos 从0开始
        """
        if pos <= 0:
            self.add(item)
        elif pos > (self.length()-1):
            self.append(item)
        else:
            cur = self.__head
            count = 0
            while count < pos:
                count += 1
                cur = cur.next
            # 当循环退出后,cur指向pos位置
            node = Node(item)
            node.next = cur
            node.prev = cur.prev
            cur.prev.next = node
            cur.prev = node

remove (item) to delete node

Delete doubly linked list node does not need to be as two cursors as a single linked list, because there prev can point to the previous node, with only a cur on it. Chain and a plurality of intermediate nodes Delete: cur moved to a position to remove the node, then the previous and the subsequent node whose node is connected to a point. If the node is the first: direct head node points to the original second node need only consider the case of a node. If the node is the end of any operation is not required, this will be determined. Specific code as follows:

    def remove(self, item):
        """删除节点"""
        cur = self.__head
        while cur != None:
            if cur.elem == item:
                # 先判断此结点是否是头节点
                # 头节点
                if cur == self.__head:
                    self.__head = cur.next
                    if cur.next:
                        # 判断链表是否只有一个结点
                        cur.next.prev = None
                else:
                    cur.prev.next = cur.next
                    if cur.next:
                    # 判断是否是尾结点
                        cur.next.prev = cur.prev
                break
            else:
                cur = cur.next

test:

The following is the test code:

if __name__ == "__main__":
    dll = DoubleLinkList()
    print(dll.is_empty())
    print(dll.length())
    dll.append(1)
    print(dll.is_empty())
    print(dll.length())
    dll.append(2)
    dll.add(8)
    dll.append(3)
    dll.append(4)
    dll.append(5)
    dll.append(6)
    dll.insert(-1, 9) 
    dll.travel()
    dll.insert(3, 100) 
    dll.travel()
    dll.insert(10, 200) 
    dll.travel()
    dll.remove(100)
    dll.travel()
    dll.remove(9)
    dll.travel()
    dll.remove(200)
    dll.travel()

Here Insert Picture Description

One-way circular list

Here Insert Picture Description
Way is to increase the circular list based on a single list of the first node pointing to the tail of the node "pointer", so that the entire list has become a circle, can cycle through. Unidirectional circular list of nodes is defined as follows:

class Node(object):
    """节点"""
    def __init__(self, elem):
        self.elem = elem
        self.next = None

Initialize function is as follows:

lass SingleCycleLinkList(object):
    """单向循环链表"""
    def __init__(self, node=None):
        self.__head = node
        if node:
            node.next = node

If a non-empty list node.next = node, i.e. there is a junction point node.

Unidirectional operation circular list

  • Whether is_empty () determines the list is empty
  • length () Returns the length of the list
  • travel () traversal
  • add (item) is added at a head node
  • append (item) to add a node in the tail
  • insert (pos, item) pos add nodes in the specified position
  • remove (item) to delete a node
  • search (item) to find whether there is a node

Single chain straight down operation different code segments Ha!

length () Returns the length of the list

The list with the single difference is that this count is = 1, single list is 0, because the single list of conditions is cur == None deadline, and here is cur.next = = self .__ head, cur point is the last node, from 1 to count, from the single list is None 0 count.

    def length(self):
        """链表长度"""
        if self.is_empty():
            return 0
        # cur游标,用来移动遍历节点
        cur = self.__head
        # count记录数量
        count = 1
        while cur.next != self.__head:
            count += 1
            cur = cur.next
        return count

travel () traversal

    def travel(self):
        """遍历整个链表"""
        if self.is_empty():
            return
        cur = self.__head
        while cur.next != self.__head:
            print(cur.elem, end=" ")
            cur = cur.next
        # 退出循环,cur指向尾节点,但尾节点的元素未打印
        print(cur.elem)

add (item) is added at a head node

If not empty, the operation is consistent with the single linked list, it is noted that there is directed from the end node to the first node. If the list is empty, directly to the junction point to the first node to be added.

    def add(self, item):
        """链表头部添加元素,头插法"""
        node = Node(item)
        if self.is_empty():
            self.__head = node
            node.next = node
        else:
            cur = self.__head
            while cur.next != self.__head:
                cur = cur.next
            # 退出循环,cur指向尾节点
            node.next = self.__head
            self.__head = node
            # cur.next = node
            cur.next = self.__head

append (item) to add a node in the tail

The first point to note nodes.

    def append(self, item):
        """链表尾部添加元素, 尾插法"""
        node = Node(item)
        if self.is_empty():
            self.__head = node
            node.next = node
        else:
            cur = self.__head
            while cur.next != self.__head:
                cur = cur.next
            # node.next = cur.next
            node.next = self.__head
            cur.next = node

insert (pos, item) pos add nodes in the specified position

pos <= 0 end inserted, pos> Table long tail plug. Then inserted in the middle of the head and tail nodes does not involve the relationship, it is completely inserted into a single list.

    def insert(self, pos, item):
        """指定位置添加元素
        :param  pos 从0开始
        """
        if pos <= 0:
            self.add(item)
        elif pos > (self.length()-1):
            self.append(item)
        else:
            pre = self.__head
            count = 0
            while count < (pos-1):
                count += 1
                pre = pre.next
            # 当循环退出后,pre指向pos-1位置
            node = Node(item)
            node.next = pre.next
            pre.next = node

remove (item) to delete a node

Delete here quite a bit of trouble, we need to consider many cases, provide an additional idea is to determine the length of the list, and then delete it.

    def remove(self, item):
        """删除节点"""
        if self.is_empty():
            return
        cur = self.__head
        pre = None
        while cur.next != self.__head:
            if cur.elem == item:
                # 先判断此结点是否是头节点
                if cur == self.__head:
                    # 头节点的情况
                    # 找尾节点
                    rear = self.__head
                    while rear.next != self.__head:
                        rear = rear.next
                    self.__head = cur.next
                    rear.next = self.__head
                else:
                    # 中间节点
                    pre.next = cur.next
                return
            else:
                pre = cur
                cur = cur.next
        # 退出循环,cur指向尾节点
        if cur.elem == item:
            if cur == self.__head:
                # 链表只有一个节点
                self.__head = None
            else:
                # pre.next = cur.next
                pre.next = self.__head

With test code and results are almost in front of here.

postscript

Photos from the part of the code and the information I learn !
This is the end part of the list, seemingly up a lot of pink, ha ha. Again that I am here to write a blog on something tall not to say so what, is to record and share their own learning process, after all, there are a lot of newcomers to CSDN learning, may write some things do not meet your appetite, do not spray me , then spray it down from your fences!
If you think I wrote something a bit with the words, welcome to point a wave of concern, we Come together A pair!

Novice, limited technology, do not like do not spray

Published 20 original articles · won praise 247 · views 20000 +

Guess you like

Origin blog.csdn.net/qq_43779324/article/details/105013067