python算法与数据结构(4)单链表

1.概念:

线性结构: 内存连续,下标结构
链式结构: 不连续,无下标,append(追加方便)find(遍历)
单链结构: root ( 入口) --> head(头节点)–>node/next( 节点和指针)–>… tail (尾节点)

2 数据和方法

单链表需要的数据是:构造节点,长度
linked list data : root ,length

方法有:初始化,增加,左侧增加,迭代节点,移除,查找,右边弹出

method: init , append, append left, iter_node, remove, find, popleft

3代码实现:

class Node(object):
    def __init__(self, value=None, next=None):
        self.value, self.next = value, next

class LinkedList(object):
    def __init__(self, maxsize=None):
    	#初始化,长度,生成节点,尾结点目前是空
        self.maxsize = maxsize
        self.root = Node()
        self.length = 0
        self.tailnode = None

    def __len__(self):
    	# 返回长度
        return self.length

    def append(self, value):
        # 增加节点
        if self.maxsize is not None and len(self) > self.maxsize:
        # 判断链表是否已经最大,返回满了
            return Exception("Full")
        node = Node(value)  # 将值作为一个节点
        tailnode = self.tailnode # 再声明一下尾结点
        if tailnode is None:  # 没有尾结点,就是说这是第一个节点,
        # 第一个插入的值作为root入口的下一个节点。即作为根节点的下一个节点,为头结点。
            self.root.next = node
        else:
            tailnode.next = node  # 后面每加一个值就作为尾节点。
        self.tailnode = node # 当前加入的节点赋值给尾结点。
        self.length += 1  # 长度加1

    def appendLeft(self, value):
    	# 从左侧加一个节点
        headnode = self.root.next  # 借用一个中间变量放老的头结点
        node = Node(value)  # 将当前值生成节点值
        self.root.next = node  # 将当前节点作为根节点的下一个节点。
        node.next = headnode  # 当前节点的下一个节点就是老的头结点。 
        self.length += 1  # 长度加1

    def iter_node(self):
        # 遍历节点,每次返回当前节点的下一个节点
        currnode = self.root.next
        while currnode is not self.tailnode:
            yield currnode
            currnode = currnode.next
        yield currnode  # 返回最后的尾节点

    def __iter__(self):  # 需要和上面函数配合完成遍历节点
        for node in self.iter_node():
            yield node.value  # 生成节点的值

    def remove(self, value):  # O(n)
    	# 移除一个节点
        prenode = self.root
        currnode = self.root.next
        while currnode.next is not None:  # 在到最后一个节点之前
            if currnode.value == value: # 如果找到要删除的节点
                prenode.next = currnode.next  
                # 让当前节点的前一个节点的next指向当前节点的下一个节点
                del currnode  # 删除这个节点
                self.length -= 1  # 长度减1
                return

    def find(self, value):  # O(n)
    	# 查找也是从头到尾遍历一遍  
        index = 0
        for node in self.iter_node():
            if node.value == value:
                return index  # 找到了,返回他的下标。
            index += 1
        return -1

    def popleft(self):  # O(1)
        if self.root.next is None:  # 先判断是不是空
            raise Exception("pop from empty.")
        headnode = self.root.next  # 头结点
        self.root.next = headnode.next  #根节点的next指向头结点的next
        self.length -= 1  # 长度减一
        value = headnode.value
        del headnode
        return value

    def clear(self):  # 清除节点,全部删除
        for node in self.iter_node():
            del node
        self.root.next = None
        self.length = 0


def test_linked_list():
    ll = LinkedList()

    ll.append(0)
    ll.append(1)
    ll.append(2)

    assert len(ll) == 3
    assert ll.find(2) == 2
    assert ll.find(3) == -1

    ll.remove(0)
    assert len(ll) == 2
    assert ll.find(0) == -1

    assert list(ll) == [1, 2]

    ll.appendLeft(0)
    assert list(ll) == [0, 1, 2]
    assert len(ll) == 3

    headvalue = ll.popleft()
    assert headvalue == 0
    assert len(ll) == 2
    assert list(ll) == [1, 2]

    ll.clear()
    assert len(ll) == 0

4然后使用pytest 做单测:

命令行 pytest +文件名 会自动运行测试以test_开头的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值