实现双向链表,并封装成容器

class ListNode: #结点保存内容和下一跳
    def __init__(self, item, next=None,prev=None):
        self.item = item
        self.next = next
        self.prev = prev  #增加上一跳

    def __repr__(self):
        return '{} <== {} ==> {}'.format(
            self.prev.item if self.prev else None,
            self.item,
            self.next.item if self.next else None
        )

class LinkedList:
    def __init__(self):
        self.head = None
        self.tail = None
        self._size = 0

    def append(self, item):
        node = ListNode(item)
        if self.head is None:
            self.head = node  #设置开头结点,以后不变
        else:
            self.tail.next = node   #更新当前的tail结点的next
            node.prev = self.tail
        self.tail = node

        self._size += 1

        return self       #链式编程

    def insert(self, index, item):
        if index >= len(self):
            self.append(item)
            return
        if index < -len(self):
            index = 0

        current = self[index]

        node = ListNode(item)
        prev = current.prev   #这两行可不写,只是为了简化
        next = current
        if prev is None:    #操作开头 index is 0
            self.head = node
        else:                       #操作中间
            node.prev = prev
            prev.next = node
        next.prev = node
        node.next = next

        self._size += 1

    def pop(self):
        """末尾弹出"""
        if self.tail is Node:
            raise Exception('Empty')

        node = self.tail
        item = node.item
        prev = node.prev
        if prev is None:
            self.head = None
            self.tail = None
        else:
            prev.next = None
            self.tail = prev

        self._size -= 1
        return item

    def remove(self, index):
        '''指定index移除'''
        if self.tail is None:
            raise Exception('Empty')

        current = self[index]

        prev = current.prev   #当前被移除节点的上一个
        next = current.next   #当前被移除节点的下一个
        if prev is None and next is None:   #只有一个结点,改头、尾
            self.head = None
            self.tail = None
        elif prev is None:        #不止一个;改头
            self.head = next
            next.prev = None
        elif next is None:        #改尾
            self.tail = prev
            prev.next = None
        else:                     #在中间
            prev.next = next
            next.prev = prev
        # return self
        del current
        self._size -= 1

    def iternodes(self, reverse=False):   #返回一个惰性对象
        current = self.tail if reverse else self.head
        while current:
            yield current
            current = current.next if not reverse else current.prev
    size = property(lambda self:self._size)

    #容器化
    def __len__(self):
        return self.size

    __iter__ = iternodes

    def __revesed__(self):
        return self.iternodes(True)

    def __getitem__(self, index):
        if index >= len(self) or index < -len(self):
            raise IndexError('Wrong index{}'.format(index))
        reverse = False if index >= 0 else True
        start = 0 if index >= 0 else 1

        for i, node in enumerate(self.iternodes(reverse), start):
            if i == abs(index):
                return node

    def __setitem__(self, index, value):
        self[index].item = value


ll = LinkedList()
ll.append('abc')
ll.append(1).append(2).append(3).append(4).append(5)
ll.append('def')
print('~~~~~~~~~~~~~~~~~')
print(ll.head)
print(ll.tail)
print('-------------------')
for item in ll.iternodes():
    print(item)

print(len(ll))
ll.remove(6)
ll.remove(5)
ll.remove(0)
ll.remove(1)
print('_' * 30 )
for item in ll:
    print(item)

ll.insert(3, 50)
ll.insert(20,'end')
ll.insert(0,'start')
print('=' * 30 )
for item in ll:
    print(item)

print('*' * 30)
print(ll[-1], len(ll), ll[5])
print(ll[-6],ll[0])

print('------------')
for x in reversed(ll):
    print(x)


 

你可能感兴趣的:(实现双向链表,并封装成容器)