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))
    
  • 相关阅读:
    PopuWindow和软件盘共存时的设置
    sql语句备份/导入 mysql数据库或表命令
    Cocos2d-x3.0游戏实例之《别救我》第八篇——TiledMap实现关卡编辑器
    mongodb文档支持的数据类型
    Longest Common Prefix -最长公共前缀
    【JDBC】java程序通过jdbc连接oracle数据库方法
    大型站点技术架构(五)--站点高可用架构
    CF981H K Paths
    带WHERE子句的UPDATE语句
    简单的数据更新
  • 原文地址:https://www.cnblogs.com/keithtt/p/9711037.html
Copyright © 2011-2022 走看看