• 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()
  • 相关阅读:
    element-ui 和ivew-ui的table导出export纯前端(可用)
    webstrom 2019 注册码(可用 2019年10月14日08:59:18)
    intellji IDEA 2019版激活码(亲测可用 2019年10月14日08:53:54)
    java开发相关工具安装包分享
    js有关字符串拼接问题
    js增删class的方法
    有关定位问题
    关于网页元素居中常见的两种方法
    有关css编写文字动态下划线
    js获取时间及转化
  • 原文地址:https://www.cnblogs.com/LanTianYou/p/8652639.html
Copyright © 2020-2023  润新知