【笨办法学python 进阶版】【ex14_DoubleLinkedList】笨办法实现--DoubleLinkedList

一、看了一段时间的kubernetes,最近又开始看“笨办法了”, 哈哈,记录一下做题的情况:
pycarhm,python3.8.3(由于换笔记本了,顺便升级了python版本)
二、做题思路,我画了几个图,方便以后看的时候好理解
shift和push的方法:
在这里插入图片描述
remove中间节点的思路:
在这里插入图片描述
unshift和pop的思路:
在这里插入图片描述
三、看了zed的视频,感觉还是跟不上,但是他强调的伪代码还不错,写清楚思路,剩下就是依葫芦画瓢的事情了,另外强调一下书中特别说明的几点:
1、如果元素个数为0,self.end和self.begin需要设置为None;
2、如果只有一个元素,self.end和self.begin都需要指向同一节点;
3、第一个元素的prev必须是None;
4、最后一个元素的next必须是None

四、脚本
测试脚本:test_dllist.py

from dllist import *

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


def test_pop():
    colors = DoubleLinkedList()
    colors.push("Magenta")
    colors.push("Alizarin")
    colors.push("yue")
    assert colors.count() == 3
    assert colors.pop() == "yue"
    assert colors.count() == 2
    assert colors.pop() == "Alizarin"
    assert colors.count() == 1
    assert colors.pop() == "Magenta"
    assert colors.count() == 0
    assert colors.pop() == None



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

    assert colors.count() == 2
    colors.shift("yue")
    assert colors.count() == 3
    assert colors.pop() == "Cadmium Orange"
    assert colors.count() == 2
    assert colors.pop() == "Carbazole Violet"
    assert colors.pop() == "yue"
    assert colors.count() == 0

def test_unshift():
    colors = DoubleLinkedList()
    colors.push("Viridian")
    colors.push("Sap Green")
    colors.push("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.dump("before perinone.")
    assert colors.remove("Perinone") == 2
    colors.dump("after perinone.")
    assert colors.remove("Nickle Yellow") == 1
    assert colors.remove("Zinc White")  == 0


def test_first():
    colors = DoubleLinkedList()
    colors.push("Cadmium Red Light")
    assert colors.first() == "Cadmium Red Light"
    colors.push("Hansa Yellow")
    assert colors.first() == "Cadmium Red Light"
    colors.shift("Pthalo Green")
    assert colors.first() == "Pthalo Green"

def test_last():
    colors = DoubleLinkedList()
    colors.push("Cadmium Red Light")
    assert colors.last() == "Cadmium Red Light"
    colors.push("Hansa Yellow")
    assert colors.last() == "Hansa Yellow"
    colors.shift("Pthalo Green")
    assert colors.last() == "Hansa Yellow"


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
########
print("hello~~~~~")
test_push()
test_pop()
test_shift()
test_unshift()
test_remove()
test_last()
test_first()
test_get()
print("All done~~~~~")

dllist.py


import sys
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):
    ### 在最后面增加一个node
        node = DoubleLinkedListNode(obj, None, None)
        if self.end == None and self.begin == None:
            self.end = node
            self.begin = node
        else:
    ##end.next = node, node.prev = end, end = node
            self.end.next = node
            node.prev = self.end
            # self.end.next = node
            self.end = node

    def count(self):
    ##数一下有多少个元素
        node = self.begin   ##只有头节点能保存完整的数据
        count = 0
        while node:
            node = node.next
            count += 1
        return count

    def pop(self):
    ##删除最后一个node,并且返回她
        # self.end.prev.next = None
        if self.end == self.begin:
            if self.end == None and self.begin == None:
                return None
            else:
                end_value = self.end.value
                self.end = None
                self.begin = None
                return end_value
        else:
            end_value = self.end.value
            self.end = self.end.prev
            self.end.next = None
            return end_value

    def shift(self, obj):
    ##从第一个node插入
        node = DoubleLinkedListNode(obj, None, None)
        if self.begin == None and self.end == None:
            self.end = node
            self.begin = node
        else:
    ##begin.prev=node, node.next = begin, begin = node
            # self.begin.prev = node
            node.next = self.begin
            self.begin.prev = node
            self.begin = node

    def unshift(self):
    ##从第一个node开始删除
        if self.begin == self.end:
            if self.begin == None and self.end == None:
                return None
            else:
                begin_value = self.begin.value
                self.begin = None
                self.end = None
                return begin_value
        else:
            begin_value = self.begin.value
            self.begin = self.begin.next
            self.begin.prev = None
            return begin_value

    def dump(self, mark):
        print(mark)
        print(">>>>>>>>>>>>")
        node = self.begin
        while node:
            print(node)
            node = node.next

    def remove(self, obj):
        node = self.begin
        count = 0
        while node:
        ###链表不止一个值,但是第一个被取到的情况
            if self.end != self.begin and self.begin.value == obj:
                self.begin = self.begin.next
                self.begin.prev = None
                break
        ###链表只有一个的情况
            elif self.end == self.begin:
                self.begin = None
                self.end = None
                break
        ###obj在链表末尾的情况
            elif self.end.value == obj:
                self.end = self.end.prev
                self.end.next = None
                count = self.count()
                break
        ###obj在链表中间的情况
            elif node.value == obj:
                node.prev.next = node.next
                node.next.prev = node.prev
                break
            node = node.next
            count += 1
        return count

    def first(self):
        return self.begin.value

    def last(self):
        return self.end.value

    def get(self, index):
    ##空链表以及取值大于链表长度的情况要返回None
        if self.begin == None and  self.end == None or index + 1 > self.count():
            return None
    #取头链表
        elif index == 0:
            return self.begin.value
    #取尾链表
        elif index == self.count() - 1:
            return self.end.value
        else:
            node = self.begin
            while index:
                node = node.next
                index = index - 1
            return node.value

五、说明
1、大家可以看一下《笨办法学python》作者链接:https://learncodethehardway.org/more-python-book/
作者github:https://github.com/zedshaw/learn-more-python-the-hard-way-solutions
可以看一下zed的源码以及处理思路。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值