笨办法学python续 learn more python3 in hard way ex14 双向链表

代码:
我的源码:
https://github.com/theguyisnoone/impthw/tree/master/ex14

class DoubleLinkedListNode(object):
    def __init__(self,value,nxt,prev):
        self.value=value
        self.next=nxt
        self.prev=prev

    def  __repr__(self):
        nval=self.next and self.next.value or None
        pval=self.prev  and self.prev.value or None
        return f"[{self.value},{repr(nval)},{repr(pval)}]"

class DoubleLinkedList(object):

    def __init__(self):
        self.begin=None
        self.end=None

    def push(self,obj):
        #if there are contents
        if self.end:
            node=DoubleLinkedListNode(obj,None,self.end)
            #node.next=new node
            self.end.next=node
            #new node  is end
            self.end=node
        #else begin  and end are new node with none
        else:
            #链表的begin&end都连接node(无需prev和next)
            node=DoubleLinkedListNode(obj,None,None)
            self.begin=node
            self.end=node

    def pop(self):
        """Removes the last item and returns it."""
        # if we have some
        if self.end:
            # get the end node
            node = self.end
            # if there is one
            if self.end == self.begin:
                self.end = None
                self.begin = None
            else:
                # detach end and reset it
                # end = end.prev
                self.end = node.prev
                # end.next = None
                self.end.next = None
                # if there's now one left, set begin to end
             
            return node.value
        else:
            return None

    def get(self,index):
        """get the value at index"""
        node=self.begin
        i=0
        while node:
            if i==index:#找到了返回值
                return node.value
            else:#不然遍历
                i += 1
                node=node.next
        return None

    def shift(self,obj):
        """just another name for push"""
        self.push(obj)


    def unshift(self):
        """remove the first item(from begin) and returns it"""
        #if we have one  at begin
        if self.begin:
            #save the begin
            node=self.begin
            #if we have only None
            if self.begin ==self.end:
                #clear begin and end
                self.begin=None
                self.end=None
            #else  we have more
            else:
                #set begin to begin.next
                self.begin=node.next
                #set begin.prev to none
                self.begin.prev=None
            #return the value
            return node.value
        #else self.begin =None
            return  None

 
    def count(self):
         """Counts the number of elements in the list."""
         # do the slow count code from single linked lists
         node=self.begin
         count=0
         while node:
             count+=1
             node=node.next
         return count


    def _invariant(self):
        if self.begin == None:#链表头为空,尾巴也要空
            assert self.end==None ,"End set while begin is not."

        if self.begin:#如果链表不为空
            assert self.begin.prev ==None,"begin.prev not noen"#头没有前驱
            assert self.end.next ==None,"end.next not null"    #尾没有后继

    def detach_node(self,node):
        #if the node is at the end
        if self.end ==node:
            self.pop()
        #elif it's at the beginning
        elif self.begin == node:
            self.unshift()
        #else it's in the middle
        else:
            #skip over it
            #save node.prev,node.next
            prev=node.prev                                                                                                                                                                                                                                                                   
            nxt=node.next
            #set prev.next to saved next
            prev.next=nxt
            #set next.prev to saved prev
            nxt.prev=prev

    def remove(self,obj):
        """Finds a matching item and removes it from the list."""
        #start at begin
        node=self.begin
        #keep the count as return value
        count=0
        #while we have a node
        while node:
            #if the node.value matches object
            if node.value == obj:
                self.detach_node(node)
                return count
            else:
                count+=1
                node=node.next
        #return -1  to indicate not there
        return -1

    def first(self):
        """return a reference to the first item doesn't remove"""
        return self.begin and self.begin.value or None

    def last(self):
        """return a reference to the first item doesn't remove"""
        return self.end and self.end.value or None

    def dump(self,mark="----"):
        #set node to begin
        node=self.begin
        print(mark)
        #while there's a node,print it out
        while node:
            print(node,end=" ")
            #next node
            node=node.next
        #print new line
        print()

#####test########
 
# colors=DoubleLinkedList()
# #push()
# colors.push("first")
# print(f"'begin:'{colors.begin}'end:'{colors.end}")
# print(colors.count())
# colors.push("second")
# print(f"'begin:'{colors.begin}'end:'{colors.end}")
# print(colors.count())
# colors.push("third")
# print(f"'begin:'{colors.begin}'end:'{colors.end}")
# print(colors.count())
#
# #pop()
# print('>>>first pop')
# colors.pop()
# print(f"'begin:'{colors.begin}'end:'{colors.end}")
# print('>>>second pop')
# colors.pop()
# print(f"'begin:'{colors.begin}'end:'{colors.end}")
# print('>>>third pop')
# colors.pop()
# print(f"'begin:'{colors.begin}'end:'{colors.end}")

#remove()
colors = DoubleLinkedList()
colors.push("Cobalt")
colors.push("Zinc White")
colors.push("Nickle Yellow")
colors.push("Perinone")
print(f"all:{colors.count()}")
print(f"first:{colors.first()}")#first()
print(f"last:{colors.last()}")#last()
print(colors.remove("Cobalt"))
print(f"now:{colors.count()}")
colors.dump("before perinone")
print(colors.remove("Perinone"))
colors.dump("after perinone")
print(f"now:{colors.count()}")
print(colors.remove("Nickle Yellow"))

自动测试代码:

from dllist import *


def test_push():
    colors = DoubleLinkedList()
    colors.push("Pthalo Blue")
    colors._invariant()
    assert colors.count() == 1
    colors.push("Ultramarine Blue")
    assert colors.count() == 2
    colors._invariant()

def test_pop():
    colors = DoubleLinkedList()
    colors.push("Magenta")
    colors._invariant()
    colors.push("Alizarin")
    colors.push("Van Dyke")
    colors._invariant()
    assert colors.pop() == "Van Dyke"
    colors._invariant()
    assert colors.get(1) == "Alizarin"
    assert colors.pop() == "Alizarin"
    assert colors.pop() == "Magenta"
    colors._invariant()
    assert colors.pop() == None

def test_get():
    colors = DoubleLinkedList()
    colors.push("Vermillion")
    assert colors.get(0) == "Vermillion"
    colors.push("Sap Green")
    assert colors.get(0) == "Vermillion"
    assert colors.get(1) == "Sap Green"
    colors.push("Cadmium Yellow Light")
    assert colors.get(0) == "Vermillion"
    assert colors.get(1) == "Sap Green"
    assert colors.get(2) == "Cadmium Yellow Light"
    assert colors.pop() == "Cadmium Yellow Light"
    assert colors.get(0) == "Vermillion"
    assert colors.get(1) == "Sap Green"
    assert colors.get(2) == None
    colors.pop()
    assert colors.get(0) == "Vermillion"
    colors.pop()
    assert colors.get(0) == None

def test_shift():
    colors = DoubleLinkedList()
    colors.shift("Cadmium Orange")
    assert colors.count() == 1

    colors.shift("Carbazole Violet")
    assert colors.count() == 2

    assert colors.pop() == "Carbazole Violet"
    assert colors.count() == 1
    assert colors.pop() == "Cadmium Orange"
    assert colors.count() == 0

def test_unshift():
    colors = DoubleLinkedList()
    colors.shift("Viridian")
    colors.shift("Sap Green")
    colors.shift("Van Dyke")
    assert colors.unshift() == "Viridian"
    assert colors.unshift() == "Sap Green"
    assert colors.unshift() == "Van Dyke"
    assert colors.unshift() == None

def test_remove():
    colors = DoubleLinkedList()
    colors.push("Cobalt")
    colors.push("Zinc White")
    colors.push("Nickle Yellow")
    colors.push("Perinone")
    assert colors.remove("Cobalt") == 0
    colors._invariant()
    # colors.dump("before perinone")
    assert colors.remove("Perinone") == 2
    colors._invariant()
    # colors.dump("after perinone")
    assert colors.remove("Nickle Yellow") == 1
    colors._invariant()
    assert colors.remove("Zinc White") == 0
    colors._invariant()

运行截图:非自动化 zed讲用pip装pytest 我还用的nosetests pytest -xs 好像这个能输出
在这里插入图片描述

笔记:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值