Python实现双向链表

本文深入探讨了如何在Python中实现双向链表,涵盖了数据结构的基础知识,以及使用指针进行节点操作的关键算法。

Python双向链表

class DwLinkedList:
    class Node:
        """
        结点类 用于存放数值以及前后指针
        """

        def __init__(self, value, last, next=None):
            self.value = value
            self.last = last
            self.next = next

    def __init__(self):
        """
        创建一个结点 第一个结点用来存放长度,方便把第一个当作普通结点处理
        """
        self.head = self.Node(0, None)
        self.tail = self.head
        self.head.value = 0

    def append(self, value):
        """
        插入一个值到链表末端
        由于存在一个用于存储长度的结点 第一个与其他结点可以统一处理
        :param value: 需要存放的数值
        :return:
        """
        self.tail.next = self.Node(value, self.tail)
        self.tail = self.tail.next
        self.head.value += 1

    def pop(self):
        """
        删除最后一个结点并返回其值
        让未指针指向倒数第二个 并让倒数第二个的next指向None
        :return: 最后一个结点的值
        """
        if self.head.value > 0:
            retValue = self.tail.value
            self.tail = self.tail.last
            self.tail.next = None
            self.head.value -= 1
            return retValue

    def insert(self, value, index):
        """
        插入一个值到索引处
        :param value: 插入的值
        :param index: 索引
        :return:
        """
        # 如果索引越界或者链表为空 调用append方法插入到末端
        if index >= self.head.value or self.head.value == 0:
            self.append(value)
        else:
            # 通过类方法__index_value来索引要插入位置处的结点
            next_node = self.__index_value(index)
            # 使用一个二元组拆包将插入结点赋给前后结点的next和last
            next_node.last.next, next_node.last = (self.Node(value, next_node.last, next_node),) * 2
            self.head.value += 1

    def remove(self, index):
        """
        移除索引处的值
        :param index: 索引
        :return:
        """
        rm_node = self.__index_value(index)
        # 如果移除的值是最后一个 则调用pop方法
        if rm_node is self.tail:
            self.pop()
        else:
            rm_node.last.next = rm_node.next
            rm_node.next.last = rm_node.last
            self.head.value -= 1

    def __len__(self):
        return self.head.value

    def __iter__(self):

        # 第一个结点的值是长度
        cur = self.head.next
        while cur:
            yield cur.value
            cur = cur.next

    def __index_value(self, key):
        """
        返回对应索引处的结点
        :param key: 索引
        :return: 结点 class self.Node实例
        """
        # 如果是负索引,将其转换为正索引 反向越界则为0
        if key < 0:
            key = self.head.value + key if self.head.value > -key else 0

        # 索引越界
        if key >= self.head.value:
            raise IndexError

        # 判断索引位置选择正反向查找
        if key < self.head.value / 2:
            cur = self.head.next
            for _ in range(key):
                cur = cur.next
        else:
            cur = self.tail
            item = self.head.value - key - 1
            for _ in range(item):
                cur = cur.last

        return cur

    def __setitem__(self, key, value):

        self.__index_value(key).value = value

    def __getitem__(self, item):

        return self.__index_value(item).value

    def __str__(self):
        # [DwLinkedList : 0 <-> 1 <-> 2 <-> 3 <-> 4 <-> 5 <-> 6 <-> 7 <-> 8 <-> 9]
        return '[DwLinkedList : {}]'.format(' <-> '.join(map(str, self)))

    def iter_reverse(self):
        """
        反向迭代
        :return: 生成器
        """
        cur = self.tail
        for _ in range(self.head.value):
            yield cur.value
            cur = cur.last
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值