Python的数据结构

目的:

这个随笔可以是看做是一个笔记,会记录一些自己觉得有意义或是有趣的或是优雅的或是......所以随笔的整体会比较凌乱,看到了这部分内容或许就会记录进来,好记性不如烂笔头,也给以后的自己翻阅提供一些回忆的素材。

实现一个“看上去很像分数”的数据结构

class Fraction:
    def __init__(self,top,bottom):
        """
        :param top:  Fractional molecule
        :param bottom: Denominator of fraction
        """
        self.top = top
        self.bottom = bottom
    def show(self):
        print( self.top,"/",self.bottom )
    #写一个方法放两个分数可以相加
    def __add__(self, other):
        newtop = self.top*other.bottom + self.bottom*other.top
        newbottom = self.bottom * other.bottom
        return Fraction(newtop , newbottom)

f1=Fraction(1,2)#1 /2
f2=Fraction(3,4)#3 /4
(f1 + f2).show()#10 / 8

这时候我们希望它显示的不只是10/8,而是5/4,显示出来最简分数,这时候我们需要用到欧几里得算法,即:如果两个数m和n,m可以被n整除,那么最大公约数就是n;如果m不能被n整除,则取n与m除以n的余数的最大公因数

def gcd(m,n):
    while (newn :=m % n) !=0:
        m = n
        n = newn
    return n

 由此我们去优化我们代码

    def __add__(self, other):
        newtop = self.top*other.bottom + self.bottom*other.top
        newbottom = self.bottom * other.bottom
        _gcd=gcd(newtop,newbottom)
        return Fraction(newtop // _gcd, newbottom // _gcd)

 栈

栈也被称作“下推栈”。它是有序集合,添加操作和移除操作总发生在同一端,即“顶端”,另一端则被称为“底端”。它的排序原则被称作LIFO(last-in first-out),即后进先出

class Stack:
    def __init__(self):
        self.items=list()

    def isEmpty(self):
        return self.items == []

    def push(self,item):
        self.items.append(item)

    def pop(self):
        return self.items.pop()

    def peek(self):
        return self.items[-1]

    def size(self):
        return len(self.items)

 双端队列

它有一前、一后两端,元素在其中保持自己的位置。与队列不同的是,双端队列对在哪一端添加和移除元素没有任何限制。它并不要求按照这两种数据结构分别规定的LIFO原则和FIFO原则操作元素。具体的排序原则取决于其使用者。

class Deque:
    def __init__(self):
        self.items = list()

    def isEmpty(self):
        return self.items == []

    def addFront(self,item):
        return self.items.append(item)

    def addRear(self,item):
        return self.items.insert(0,item)

    def removeFront(self):
        return self.items.pop()

    def removeRear(self):
        return self.items.pop(0)

    def size(self):
        return len(self.items)

 链表

无序列表(unordered list)是基于节点集合来构建的,每一个节点都通过显式的引用指向下一个节点。只要知道第一个节点的位置(第一个节点包含第一个元素),其后的每一个元素都能通过下一个引用找到。

列表中的每一个元素都必须被存放在一个节点对象中(注意,保存的是节点对象)

 

class Node:
    def __init__(self,initdata):
        self.data = initdata
        self.next = None

    def getData(self):
        return self.data

    def getNext(self):
        return self.next

    def setData(self,newdata):
        self.data = newdata

    def setNext(self,newnext):
        self.next = newnext

class UnorderedList:
    def __init__(self):
        self.head = None

    def isEmpty(self):
        return self.head == None

    def add(self,item):
        temp = Node(item)
        temp.setNext(self.head)
        self.head = temp

    def length(self):
        current = self.head
        count = 0
        while current != None:
            count +=1
            current = current.getNext()
        return count

    def search(self,item):
        current = self.head
        found = False
        while current != None and not found:
            if current.getData() == item:
                found =True
            else:
                current = current.getNext()

        return found

    def remove(self,item):
        current =self.head
        previous =  None
        found = False
        while not found:
            if current.getData == item:
                found = True
            else:
                previous = current
                current=current.getNext()
        if previous ==  None:
            self.head =current.getNext()
        else:
            previous.setNext(current.getNext())

 用栈帧实现递归

注:递归一定会有两个组成部分:1.基线条件 (没有基线条件,递归会陷入死循环,基线条件告诉程序什么时候退出)2.递归条件

之前我们已经写过如果使用python去实现一个栈。今天我们使用栈去结合递归让递归更容易

假如我们现在要实现一个16进制转字符串

def toStr(n):
    baseString = "0123456789ABCDEF"
    if n <= 16:
        return baseString[n]
    else:
        return toStr(n // 16 )+baseString[n%16]

 假设不拼接递归调用toStr的结果和convertString的查找结果,而是在进行递归调用之前把字符串压入栈中

rStack = Stack()
def toStr(n):
    baseString = "0123456789ABCDEF"
    if n <= 16:
        rStack.push(baseString[n])
    else:
        rStack.push(baseString[n%16])
        toStr(n // 16 )

 

posted @ 2022-04-09 19:26  yetangjian  阅读(66)  评论(0编辑  收藏  举报