链式结构

内存空间不在需要连续

n : next 存储的是下一个值的地址

t: 上一个值的地址

v: 值的数值存储

有n有t,是双向链表结构

只有n,是单向链表结构

image-20220815233443955

在头部加数据, O(1)

删除任意一个元素的时候,n2指向v3即可,效率也很高.

如果查看v2元素是什么时候,效率就不高了,只能从第一个往下找.

代码模拟链表

# 节点对象,value和next
class Node:
    def __init__(self, value=None, next_=None):
        self.value = value
        self.next_ = next_

    def __str__(self):
        return f"Node: {self.value}"


# 链式结构
class LinkedList:
    def __init__(self):
        # 初始化根节点,根节点无数据,每次遍历都是从这里去观察,
        # 不管是在链表前 还是后加数据,都是在root.next_后面
        self.root = Node()
        # 记录链式结构的大小
        self.size = 0
        # 最后一个节点,增加新数据时, 放在这个数据后面.
        self.end = None

    # 向尾部加值
    def append(self, value):
        node = Node(value)
        if not self.end:  # 检查下一个节点是否存在,不存在,则表示此时还无数据.
            self.root.next_ = node  # 指定root的next_为node
        else:
            self.end.next_ = node  # 已经有数据,指定下一个节点的next_为node
        self.end = node
        self.size += 1

    def append_first(self, value):
        node = Node(value)

        if not self.end:  # 没有节点的时候
            self.root.next_ = node
            self.end = node
        else:  # 有节点的时候
            t = self.root.next_  # 原来root后面的节点.第一个节点
            self.root.next_ = node  # 设置新的第一个节点
            node.next_ = t  # 新的第一个节点 -> 原来的第一个节点
        self.size += 1

    def __iter__(self):
        current = self.root.next_
        if current:
            # 如果不是最后一个节点,就继续遍历
            while current is not self.end:
                yield current
                current = current.next_
            yield current

    def find(self, value):
        for n in self:
            if n.value == value:
                return f"{n} {id(n)}"

    def count(self, value):
        c = 0
        for n in self:
            if n.value == value:
                c += 1
        return c

    def remove(self, value):
        # 上一个节点
        prev = self.root
        for n in self:
            if n.value == value:
                # 上一个节点 -> 链接 下一个节点

                if n == self.end:
                    prev.next_ = None
                    self.end = prev
                else:
                    prev.next_ = n.next_
                del n
                self.size -= 1
                return True

            # 更新上一个节点
            prev = n

    def remove_all(self, value):
        # 上一个节点
        prev = self.root
        for n in self:
            if n.value == value:
                # 上一个节点 -> 链接下一个节点
                if n == self.end:
                    prev.next_ = None
                    self.end = prev
                else:
                    prev.next_ = n.next_
                del n
                self.size -= 1
                continue
            # 更新上一个节点
            prev = n


if __name__ == '__main__':
    link = LinkedList()
    link.append("孙悟空")
    link.append("猪八戒1")
    link.append("猪八戒1")
    link.append("猪八戒")
    for v in link:
        print(v)

    link.remove_all("猪八戒1")
    print("--------------")
    for v in link:
        print(v)

results matching ""

    No results matching ""