双向链表

本文介绍了如何在Python中实现双向链表,包括append、pop、remove、insert、getitem、setitem以及iter等核心功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

python实现双项链表

实现append,pop,remove,insert,getitme,setitem,iter能力

class Linked:
    
    class Node:#单个节点
        
        def __init__(self, node, lastobj=None, nextobj=None):
            self.last = lastobj
            self.next = nextobj
            self.data = node
            
        def __repr__(self):
            return f'{self.data}'

        
    def __init__(self, node):#生成节点实例,作为该链表的头
        self.head = Linked.Node(node)
        self.tail = self.head
        self.length = 1
        
    def append(self, node):
        lastobj = self.tail
        newobj = Linked.Node(node,lastobj)#生成新节点并将lastobj(已考虑为None)放入其last属性,
        if not self.length:#如果链表长度为0,设置新的head
            self.head = newobj
        else:#把lastobj的next属性更改为新节点
            lastobj.next = newobj
        self.tail = newobj
        self.length += 1
        
    def pop(self):
        ret = self.tail
        if self.length == 1:#当链表长度为1时,pop并给head,tail赋值值为None
            self.head = None
            self.tail = None
            self.length -= 1
            return ret
        try:#长度为0时,试图pop,但tail为None,None没有last属性报错,其他情况正常处理
            self.tail = self.tail.last
            self.tail.next = None
            self.length -= 1
        except:
            raise IndexError('pop from empty linkedlist')
        return ret
    
    def __iter__(self):
        node = self.head
        while node is not None:#排除node本身等效为False
            yield node
            node = node.next
            
    def remove(self, node):#已删除当node为tail时的代码
        for i in self:
            if node == i.data:
                i.last.next = i.next
                i.next.last = i.last
                self.length -= 1
                return
        raise ValueError(f'{node} not in linkedlist')

    def __getitem__(self, index):
        length = self.length#用标识符记住self的长度,防止接下来多次去字典里查找该值
        if not isinstance(index, int):
            raise ValueError('the index must be an integer')
        elif length == 0:
            raise IndexError('linkedlist assignment index out of range')
        elif index < -length or length <= index:
            raise IndexError('linkedlist index out of range')
        elif -length <= index < 0:#把负索引改为正索引
            index += length
        for i,node in enumerate(self):
            if index == i:
                return node
            
    def insert(self, index, node):
        target = self[index]
        newobj = Linked.Node(node, target.last, target)
        target.last = newobj
        try:
            newobj.last.next = newobj
        except:
            self.head = newobj
        self.length += 1

    def __setitem__(self, index, node):
        target = self[index]
        newobj = Linked.Node(node, target.last, target.next)
        try:
            newobj.last.next = newobj
        except:
            self.head = newobj
        try:
            newobj.next.last = newobj
        except:
            self.tail = newobj
        
    def __len__(self):
        return self.length

s = Linked(20)
s.append(60)
s.append(100)
print('head:{} tail:{} len:{}'.format(s.head, s.tail, len(s)))
s.pop()
s.pop()
print('head:{} tail:{} len:{}'.format(s.head, s.tail, len(s)))
s.pop()
print('head:{} tail:{} len:{}'.format(s.head, s.tail, len(s)))
#s.pop()#长度为0时,使用index操作及pop时报错,此时只能使用append
s.append('a')
print('head:{} tail:{} len:{}'.format(s.head, s.tail, len(s)))
s.insert(0,50)#
print('head:{} tail:{} len:{}'.format(s.head, s.tail, len(s)))
#s.remove('b')移除值不存在报错
s[1] = 'b'
print('head:{} tail:{} len:{}'.format(s.head, s.tail, len(s)))
for i in s:
    print(i)
head:20 tail:100 len:3
head:20 tail:20 len:1
head:None tail:None len:0
head:a tail:a len:1
head:50 tail:a len:2
head:50 tail:b len:2
50
b
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值