zoukankan      html  css  js  c++  java
  • 单向链表

    每一个结点有两个域,左边部份叫值域,用于存放用户数据。右边叫指针域,存储着指向后面一个节点的指针。
    head节点永远指向第一个节点。
    tail节点永远指向最后一个节点。

    class Node:
        def __init__(self, item, next=None):
            self.item = item
            self.next = next
    
        def __str__(self):
            return '<node: {} -> next: {}>'.format(self.item, self.next.item if self.next else None)
    
        def __repr__(self):
            return str(self.item)
    
    class LinkedList:
        def __init__(self):
            self.head = None
            self.tail = None
            self.size = 0
    
        def append(self, item):
            node = Node(item)
            if self.head is None:
                self.head = node
                self.tail = node
            else:
                self.tail.next = node
                self.tail = node
            self.size += 1
            return self
    
        def index(self, item):
            for i, node in enumerate(self):
                if item == node.item:
                    return i
            else:
                raise ValueError('item does not exist')
    
        def insert(self, index, item):
            if index < 0:
                raise IndexError
    
            # 如果找到就将current指向对应位置的节点,继续后面的操作
            # 如果没有找到(链表为空或者索引超界),则追加并立即返回,后面的操作将不会执行
            for i, node in enumerate(self):
                if i == index and node is not self.tail:
                    current = node
                    break
            else:
                self.append(item)
                return
    
            node = Node(item)
            next = current.next
    
            # 从头部插入
            if current is self.head:
                node.next = current
                self.head = node
            # 从中间插入(尾部插入即追加,上面已经实现)
            else:
                prev = self.head
                while prev.next is not current:
                    prev = prev.next
                prev.next = node
                node.next = current
    
            self.size += 1
    
        def pop(self):
            # 如果头部或尾部为空,则表示链表为空
            if self.head is None:
                raise Exception('empty')
    
            node = self.tail
            item = node.item
    
            # 如果头节点没有后节点,则表示链表只有一个元素
            if self.head.next is None:
                self.head = None
                self.tail = None
            # 剩下就是有多个节点的情况
            else:
                prev = self.head
                while prev.next is not node:
                    prev = prev.next
                prev.next = None
                self.tail = prev
    
            self.size -= 1
            return item
    
        def remove(self, index):
            if index < 0:
                raise IndexError('does not support negative index')
    
            # 如果链表为空,则抛出异常
            if self.head is None:
                raise Exception('empty')
    
            # 如果找到就将current指向对应位置的节点,继续后面的操作
            # 如果没有找到(链表为空或者索引超界),则抛出异常
            for i, node in enumerate(self):
                if i == index:
                    current = node
                    break
            else:
                raise IndexError('index out of range')
    
            next = current.next
    
            # 如果current没有前节点也没有后节点,表示只有一个节点
            if self.head.next is None:
                self.head = None
                self.tail = None
            # 如果不止一个节点,且current是head
            elif current is self.head:
                self.head = next
            # 如果不止一个节点、current不是head,且current是tail
            elif current is self.tail:
                self.pop()
            # 剩下就是多节点从中间remove的情况
            else:
                prev = self.head
                while prev.next is not current:
                    prev = prev.next
                prev.next = next
    
            self.size -= 1
    
        def clear(self):
            self.head = None
            self.tail = None
            self.size = 0
    
        def __iter__(self):
            current = self.head
            while current:
                yield current
                current = current.next
    
        def __len__(self):
            # current = self.head
            # count = 0
            # while current:
            #     count += 1
            #     current = current.next
            # return count
            return self.size
    
        def __getitem__(self, key):
            for i, node in enumerate(self):
                if key == i:
                    return node
            else:
                raise IndexError('index out of range')
    
        def __setitem__(self, key, value):
            # for i, node in enumerate(self):
            #     if key == i:
            #         node.item = value
            # else:
            #     self.append(value)
            self[key].item = value
    
    
    linklist = LinkedList()
    
    # 测试append()
    for i in range(10):
        linklist.append(i)
    
    # 测试__iter__
    for node in linklist:
        print(node)
    
    # 测试__len__
    print(len(linklist))
    
    # 测试index()
    print(linklist.index(3))
    # print(linklist.index(13))
    
    # 测试__getitem__
    print(linklist[3])
    # print(linklist[13])
    
    # 测试__setitem__
    linklist[5] = 15
    print(list(linklist))
    
    # 测试insert()
    linklist.insert(1, 10)
    print(list(linklist))
    linklist.insert(0, 0)
    print(list(linklist))
    
    # 测试pop()
    print(linklist.pop())
    
    # 测试remove()
    linklist.remove(0)
    linklist.remove(3)
    print(list(linklist))
    
    # 测试clear()
    linklist.clear()
    print(list(linklist))
    print(len(linklist))
    
  • 相关阅读:
    LeetCode 189. Rotate Array
    LeetCode 965. Univalued Binary Tree
    LeetCode 111. Minimum Depth of Binary Tree
    LeetCode 104. Maximum Depth of Binary Tree
    Windows下MySQL的安装与配置
    LeetCode 58. Length of Last Word
    LeetCode 41. First Missing Positive
    LeetCode 283. Move Zeroes
    《蚂蚁金服11.11:支付宝和蚂蚁花呗的技术架构及实践》读后感
    删除docker下的镜像
  • 原文地址:https://www.cnblogs.com/keithtt/p/9711037.html
Copyright © 2011-2022 走看看