Python3玩轉單鏈表——逆轉單向鏈表pythonic版


[本文出自天外歸雲的博客園]

鏈表是由節點構成的,一個指針代表一個方向,如果一個構成鏈表的節點都只包含一個指針,那么這個鏈表就是單向鏈表。

單向鏈表中的節點不光有代表方向的指針變量,也有值變量。所以我們定義鏈表,就是要定義鏈表中的節點,對鏈表的操作最后也就是對節點的操作。

這些包含數據的節點們在一種指定的結構下連接起來,成為了一種數據結構——單向鏈表。以上是我對單向鏈表的理解。

以下是我用python3對單向鏈表這種數據結構的一種實現,其中我用到了生成器來完成逆轉單向鏈表這一操作,非常pythonic啊!代碼如下:

'''
    Python版單向鏈表-單向鏈表簡稱單鏈表
    單鏈表中所包含的基本操作:
    初始化
    創建
    鏈表生成器
    打印
    顯示調用過程
    計算長度
    判空
    獲取
    刪除
    插入
    修改
    追加
    逆轉單向鏈表
'''


class Node(object):
    # 節點初始化
    def __init__(self, value, p=None):
        self.value = value
        self.next = p


class LinkList(object):
    # 初始化單鏈表
    def __init__(self):
        self.head = None

    # 創建單鏈表
    def create(self, node_value_list):
        self.head = Node(node_value_list[0])
        p = self.head
        for i in node_value_list[1:]:
            p.next = Node(i)
            p = p.next

    # 生成單鏈表
    def generate(self):
        p = self.head
        while p != None:
            yield p.value
            p = p.next

    # 打印單鏈表
    def print(self):
        print([i for i in self.generate()])

    # 顯示方法調用前后的單鏈表
    def show(func):
        def wrapper(self, *args):
            print("方法{func_name}執行前".format(func_name=func.__name__))
            self.print()
            print("方法{func_name}執行中".format(func_name=func.__name__))
            func(self, *args)
            print("方法{func_name}執行后".format(func_name=func.__name__))
            self.print()

        return wrapper

    # 獲取單鏈表的長度
    def length(self):
        p = self.head
        length = 0
        while p != None:
            length += 1
            p = p.next
        return length

    # 判斷單鏈表是否為空
    def is_null(self):
        return self.length() == 0

    # 獲取單鏈表偏移位元素返回並打印其節點值
    # 支持順序索引和逆序索引:0代表索引0位,-1代表倒數第一位,-2代表倒數第二位
    # 獲取不存在的位返回None
    def get(self, offset):
        p = self.head
        index = 0
        length = self.length()
        if offset > length - 1:
            print(None)
            return None
        if offset < 0 and offset + length < 0:
            print(None)
            return None
        if offset < 0 and offset + length >= 0:
            offset = length + offset
        while index < length - 1 and index < offset:
            p = p.next
            index += 1
        print("獲取索引{index}位節點-值為{value}".format(index=index, value=p.value))
        return p

    # 刪除單鏈表偏移位元素並打印
    # 支持順序索引和逆序索引:0代表索引0位,-1代表倒數第一位,-2代表倒數第二位
    # 刪除不存在的位返回None
    @show
    def remove(self, offset):
        p = self.head
        length = self.length()
        index = 0
        if offset > length - 1:
            print(None)
            return None
        if offset == 0 or offset + length == 0:
            print("刪除索引{index}位節點-值為{value}".format(index=index, value=self.head.value))
            self.head = p.next
            return None
        if offset < 0 and length + offset > 0:
            offset = length + offset
        while index < length - 1 and index < offset - 1:
            p = p.next
            index += 1
        print("刪除索引{index}位節點-值為{value}".format(index=index + 1, value=p.next.value))
        p.next = p.next.next

    # 在指定index位插入節點-值為value
    # 什么是插入——在兩個節點之間加入才叫插入
    # 所以在末尾插入的意思就是在索引倒數第二位和倒數第一位之間插入
    @show
    def insert(self, offset, value):
        length = self.length()
        # 如果偏移量對應的索引位不在鏈表對應索引位范圍內-返回None
        if offset > length - 1 or offset + length < 0:
            return None
        if offset < 0:
            offset = offset + length
        node = Node(value)
        if offset == 0 or offset + length == 0:
            p = self.head
            self.head = node
            node.next = p
        else:
            previous_node = self.get(offset - 1)
            current_node = self.get(offset)
            previous_node.next = node
            node.next = current_node
        print("在索引{index}位插入節點-值為{value}".format(index=offset, value=value))

    # 在鏈表索引末位追加一個節點-值為value
    @show
    def append(self, value):
        last_node = self.get(self.length() - 1)
        last_node.next = Node(value)

    # 修改鏈表索引位節點值
    @show
    def modify(self, offset, value):
        self.get(offset).value = value

    # 逆向生成單向鏈表
    @show
    def reverse(self):
        # 將節點生成器轉變為列表並逆序
        reverse_list = [i for i in self.generate()][::-1]
        self.head = Node(reverse_list[0])
        p = self.head
        for i in reverse_list[1:]:
            p.next = Node(i)
            p = p.next


if __name__ == '__main__':
    list = [1, 2, 33, 4, 55, 6, 76, 78]
    # 初始化鏈表
    link_list = LinkList()
    # 創建鏈表
    link_list.create(list)
    # 獲取節點
    link_list.get(-1)
    # 刪除節點
    link_list.remove(0)
    # 插入節點
    link_list.insert(-2, 0.2)
    # 末位追加節點
    link_list.append(3)
    # 修改節點值
    link_list.modify(-1, 666)
    # 逆轉
    link_list.reverse()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM