Linear table (one-way circular linked list (motion picture analysis))


Although most of the principles in this part are similar to singly linked lists. However, it analyzes "head node, only one node, intermediate node, and tail node" more than singly linked lists, and conducts detailed analysis for more complex operations. The rest of the simple part can refer to "singly linked list".

Singly circular linked list

A variant of a singly linked list is a one-way circular linked list. The next field of the last node in the linked list is no longer None, but points to the head node of the linked list.
Insert picture description here

Operation of one-way circular linked list

Node definition

The next field of the last node in the linked list is no longer None, but points to the head node of the linked list. Therefore, its node definition is obviously different from "singly linked list and doubly linked list"
Insert picture description here

// An highlighted block
class SingleLinkList(object):
    """单链表的结点"""
    def __init__(self,item=None,node=None):
        self.item = item
        self.next = None
        self._head = node
        if node:        
            node.next=node
Calculate the length of the linked list

Determine whether the next node of cur is the head node
Insert picture description here

// An highlighted block
    """链表长度"""
    def length(self):
        if self.is_empty():
            return 0
        cur = self._head  # cur初始时指向头节点
        count = 1
        while cur.next != self._head:   #判断cur的下一个节点是否为头结点
            count=count+1
            cur=cur.next  # 将cur后移一个节点
        return count
Traverse the list elements

Determine whether the next node of cur is the head node

// An highlighted block
"""遍历链表"""
    def travel(self):
        #判断是否为空链表
        if self.is_empty():
            return
        cur = self._head
        while cur.next != self._head:
            print(cur.item,end="\t")
            cur = cur.next
        #退出循环时,cur指向末尾节点,但是节点鹅元素未被打印
        print(cur.item)
Add elements to the head

First use cur to traverse all elements, find the tail node, and then point the tail node next field to the newly added element
Insert picture description here

// An highlighted block
    """头部添加元素"""
    def add(self, item):
        node = Single_CircleLinkList(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=self._head
        node = Single_CircleLinkList(item)
        node.next = self._head
        self._head = node
Add elements at the end

First use cur to traverse all elements, find the tail node, and then point the next field of the tail node to the newly added element, and the next field of the new element to the head node
Insert picture description here

// An highlighted block
"""尾部添加元素"""
    def append(self, item):
        node = Single_CircleLinkList(item)
        if self.is_empty():  # 先判断链表是否为空,若是空链表,则将_head指向新节点
            self._head = node  # 若不为空,则找到尾部,将尾节点的next指向新节点
            node.next=node
        else:
            cur = self._head
            while cur.next!= self._head:  # 判断下一个节点是否为None
                cur = cur.next
            node.next=self._head
            cur.next = node
Delete element

This part of the principle is similar to that of a singly linked list, but in the specific analysis, the empty linked list, the first element, the deletion of only one node, the deletion of the middle element and the deletion of the tail element are mixed , so it is separately analyzed. The rest are mentioned in the "one-way circular linked list", because the analysis is relatively simple, there is no separate analysis.

 """删除一个节点"""
 #单独说明  引入尾部节点 rear,尾结点是指链表中最后一个节点,在单链表中,尾结点的指针一般为空,即没有保存其他节点的存储位置信息。但在双向链表中,尾结点一般指向链表中第一个节点。
 #引入rear的原因是 通过rear游标找到最后一个节点
    def remove(self, item):
        # 若链表为空,则直接返回
        if self.is_empty():
            return
        cur = self._head
        pre = None
        while cur.next != self._head:
            if cur.item == item:
                # 先判断此节点是否为头结点
                if cur == self._head:
                    #头结点的情况
                    #先找尾节点,然后由尾节点找到指向的头节点
                    rear = self._head  
                    rear = rear.next
                    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.item==item:
            if cur==self._head:
                #链表只有一个节点
                self._head=None
            else:
                pre.next=cur.next
var foo = 'bar';
Modify elements

Find the element at the specified position, and then modify it with the specified value

// An highlighted block
    def change(self, pos,num,item=None):
        self.item = item
        # node = SingleLinkList(item)
        cur = self._head
        count = 0
            # 通过计数判断是否移动到指定位置的前一个位置
        while count < (pos - 1):
            count += 1
            cur = cur.next
        cur.item =num
Element inversion
// An highlighted block
class Node(object):
    def __init__(self, item=None, next=None):
        self.item = item
        self.next = next

    def rev(link):
        pre = link
        cur = link.next
        pre.next = None
        while cur:
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp
        return pre

if __name__ == '__main__':
    link = Node(1, Node(2, Node(3, Node(4, Node(5, Node(6, Node(7, Node(8, Node(9)))))))))
    root=link
    while root:
        print(root.item,end="\t")
        root = root.next
    print(end="\n")
    root = link.rev()
    while root:
        print(root.item,end="\t")
        root = root.next

Insert picture description here

The program runs

// An highlighted block
"""单链表的结点"""
class SingleLinkList(object):
    def __init__(self,item=None,node=None):
        self.item = item
        self.next = None
        self._head = node
        if node:
            node.next=node

    '''判断链表是否为空'''
    def is_empty(self):
        return self._head == None

    """链表长度"""
    def length(self):
        cur = self._head  # cur初始时指向头节点
        count = 0
        while cur != None:  # 尾节点指向None,当未到达尾部时
            count=count+1
            cur=cur.next  # 将cur后移一个节点
        return count

    """遍历链表"""
    def travel(self):
        cur = self._head
        while cur != None:
            print(cur.item,end="\t")
            cur = cur.next
        print(end="\n")

    """尾部添加元素"""
    def append(self, item):
        node = SingleLinkList(item)
        if self.is_empty():  # 先判断链表是否为空,若是空链表,则将_head指向新节点
            self._head = node  # 若不为空,则找到尾部,将尾节点的next指向新节点
        else:
            cur = self._head
            while cur.next!= None:  # 判断下一个节点是否为None
                cur = cur.next
            cur.next = node

    """头部添加元素"""
    def add(self, item):
        node = SingleLinkList(item)
        node.next = self._head
        self._head = node

    """在指定位置添加元素
    添加的元素是 (2,50),则pos=2
    """
    def insert(self, pos, item):
        # 判断指定位置是进行头部添加还是尾部添加
        if pos <= 0:
            self.add(item)
        elif pos > (self.length() - 1):
            self.append(item)
        else:
            node = SingleLinkList(item)
            cur = self._head
            count = 0
            # 通过计数判断是否移动到指定位置的前一个位置
            while count < (pos - 1):
                count += 1
                cur = cur.next
            node.next = cur.next
            cur.next = node

    """查找节点是否存在"""
    def search(self, item):
        cur = self._head
        while cur != None:
            if cur.item == item:
                print("True")
                return True
            else:
                cur = cur.next
        print("False")
        return False

    """删除一个节点"""
    def remove(self, item):
        # 若链表为空,则直接返回
        cur = self._head
        pre = None
        # 若头节点的元素就是要查找的元素item
        while cur != None:
            if cur.item == item:
                # 先判断此节点是否为头结点
                if cur == self._head:
                    self._head = cur.next
                else:
                    pre.next = cur.next
                break
            else:
                pre = cur
                cur = cur.next

    """在指定位置添加元素
        添加的元素是 (2,50),则pos=2
        """

    def insert(self, pos, item):
        # 判断指定位置是进行头部添加还是尾部添加
        if pos <= 0:
            self.add(item)
        elif pos > (self.length() - 1):
            self.append(item)
        else:
            node = SingleLinkList(item)
            cur = self._head
            count = 0
            # 通过计数判断是否移动到指定位置的前一个位置
            while count < (pos - 1):
                count += 1
                cur = cur.next
            node.next = cur.next
            cur.next = node

    '''修改元素'''
    def change(self, pos,num,item=None):
        self.item = item
        # node = SingleLinkList(item)
        cur = self._head
        count = 0
            # 通过计数判断是否移动到指定位置的前一个位置
        while count < (pos - 1):
            count += 1
            cur = cur.next
        cur.item =num
        
if __name__=="__main__":
    a=SingleLinkList()
    print(a.is_empty())
    print(a.length())
    #在尾部增加元素
    a.append(1)
    print(a.is_empty())
    print(a.length())
    a.append(2)
    a.append(3)
    a.append(4)
    a.append(5)
    a.append(6)
    a.travel()
    #在头部增加元素
    a.add(20000)
    a.travel()
    # # 在指定位置插入
    a.insert(3,50)
    a.travel()
    print(a.length())
    # #删除元素
    a.remove(20000)
    a.travel()
    # #查找元素
    a.search(50)
    a.search(10000)
    a.search(30000)
    a.insert(3,80)
    a.travel()
    a.change(3,100)
    a.travel()

Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_42567027/article/details/107093886