Python实现基本数据类型——栈、队列、双端队列、列表

1. 栈Stack

1.1 ADT Stack的Python实现

class Stack:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []
    
    def push(self, item):
        return self.items.append(item)

    def pop(self):
        return self.items.pop()
    #查看栈顶数据,栈不被修改
    def peek(self):
        return self.items[len(self.items)-1]

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

这个实现是借助Python中的List,把List的最右端也就是标号最大的端作为栈顶,所有的操作都在栈顶发生。

1.2 栈的应用

简单括号匹配

设计算法,判断形如"((((()))))()()())))))((()))))"的括号组成的字符串中所有的括号是否成对出现

#构造栈
class Stack:
    def __init__(self):
        self.items = []

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

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

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

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

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


def parCheck(parstring):
    parStack = Stack()
    flag = True
    index = 0
    while index < len(parstring) and flag:
        if parstring[index] == '(':
            parStack.push(parstring[index])
            print(parStack)
        else:
            if parStack.isEmpty():
                flag = False
            else:
                parStack.pop()
        index += 1
    if flag and parStack.isEmpty():
        return True
    else:
        return False

print(parCheck("(("))
print(parCheck("))(()()("))
一般括号匹配

设计算法,判断形如"({}[]{}()[][)}))"的括号组成的字符串中所有的括号是否成对出现

class Stack:
    def __init__(self):
        self.items = []

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

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

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

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

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


def parCheck(symbolString):
    s = Stack()
    balanced = True
    index = 0
    while index < len(symbolString) and balanced:
        symbol = symbolString[index]
        if symbol in "({[":
            s.push(symbol)
        else:
            if s.isEmpty():
                balanced = False
            else:
                top = s.pop()
                if not matches(top,symbol):
                    balanced = False
        index += 1

    if balanced and s.isEmpty():
        return True
    else:
        return False

def matches(pop,close):
    opens = "({["
    closers = ")}]"
    return opens.index(pop)==closers.index(close)
print(parCheck("(((((())))))))"))
print(parCheck("(())"))
print(parCheck("(((({{{}}}}})))[][][][][]}}}"))
print(parCheck("{}[]()()"))
十进制转二进制
from Stack_base import Stack

def decTobin(dec):
    remstack = Stack()
    while dec > 0:
        dec,rem = divmod(dec,2)
        remstack.push(rem)
    binstring = ""
    while not remstack.isEmpty():
        binstring = binstring + str(remstack.pop())
    return binstring

print(decTobin(333)) 

2.队列Queue

2.1 ADT Queue的Python实现

class Queue:
    def __init__(self):
        self.items=[]
    def isEmpty(self):
        return self.items == []
    def enqueue(self,item):
        self.items.insert(0,item)
    def dequeue(self):
        return self.items.pop()
    def size(self):
        return len(self.items)

2.2 队列的应用

约瑟夫问题

类似于击鼓传花,最后花在谁的手里谁就被杀掉。

from queue_base import Queue
def hotPotato(nameList,num):
    simqueue = Queue()
    for name in nameList:
        simqueue.enqueue(name)
    while simqueue.size() > 1:
        for i in range(num):
            simqueue.enqueue(simqueue.dequeue())
        simqueue.dequeue()
    return simqueue.dequeue()
print(hotPotato(["Bill","David","Susan","Jane","Kent","Brad"],7))
模拟算法:模拟打印机,判断打印机是否繁忙

问题建模

  • 三个对象:打印任务、打印队列、打印机
    打印任务的属性:提交时间、打印页数
    打印队列的属性:具有FIFO性质的打印任务队列
    打印机属性:打印速度、是否忙
  • 有两个过程:生成和提交打印任务、实施打印
  • 生成和提交打印任务:
  • 确定生成概率:实例为每小时会有10个学生提交20个作业,这样,概率是每180秒会有一个作业生成并提交,所以概率为每秒1/180.
    
  • 确定打印页数:实例是1~20页,那么就是1-20页之间的概率相同
    
  • 实施打印:
  •  当前的打印作业:正在打印的作业
    
  •  打印结束倒计时:新作业开始打印时开始倒计时,回0表示打印完毕,可以处理下一个作业
    
  • 模拟时间:
  •  统一的时间框架:以最小单位(秒)均匀流逝的时间,设定结束时间
    
  •  同步所有的过程:在一个时间单位里,对生成打印任务和实施打印任务两个过程各处理一次
    
from queue_base import Queue

import random


class Printer:
    def __init__(self, ppm):
        self.pagerate = ppm  # 打印速度
        self.currentTask = None  # 打印任务
        self.timeRemaining = 0  # 任务倒计时

    def tick(self):  # 打印一秒
        if self.currentTask != None:
            self.timeRemaining = self.timeRemaining - 1
            if self.timeRemaining <= 0:
                self.currentTask = None

    def busy(self):  # 打印忙
        if self.currentTask != None:
            return True
        else:
            return False

    def startNext(self, newtask):  # 打印新的作业
        self.currentTask = newtask
        self.timeRemaining = newtask.getPages()*60/self.pagerate


class Task:
    def __init__(self, time):
        self.timestamp = time  # 生成时间戳
        self.pages = random.randrange(1, 21)

    def getStamp(self):
        return self.timestamp

    def getPages(self):
        return self.pages

    def waitTime(self, currenttime):
        return currenttime - self.timestamp


def newPrintTask():
    num = random.randrange(1, 181)
    if num == 180:
        return True
    else:
        return False


def simulation(numSeconds, pagesPerMinute):
    labprinter = Printer(pagesPerMinute)
    printQueue = Queue()
    waitingtimes = []

    for currentSecond in range(numSeconds):
        if newPrintTask():
            task = Task(currentSecond)
            printQueue.enqueue(task)
        if (not labprinter.busy()) and\
            (not printQueue.isEmpty()):
            nexttask = printQueue.dequeue()
            waitingtimes.append(nexttask.waitTime(currentSecond))
            labprinter.startNext(nexttask)
        labprinter.tick()
    averageWait = sum(waitingtimes)/len(waitingtimes)
    print("Average Wait %6.2f secs %3d tasks remaining."%(averageWait,printQueue.size()))

for i in range(1000):
    simulation(3600,5)

3.双端队列Deque

3.1 ADT Deque的Python实现

class Deque:
    def __init__(self):
        self.items = []
    def isEmpty(self):
        return self.items == []
    def addFront(self,item):
        self.items.append(item)
    def addRear(self,item):
        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)

3.2 双端队列的应用

回文字符串的判断
from Deque_base import Deque

def palchecker(aString):
    chardeque = Deque()

    for ch in aString:
        chardeque.addRear(ch)
    stillEqual = True
    while chardeque.size() > 1 and stillEqual:
        first = chardeque.removeFront()
        last = chardeque.removeRear()
        print(first)
        print(last)
        if first != last:
            stillEqual = False
            #break
    return stillEqual

print(palchecker("lsdkjjkljlkklj"))
print(palchecker("radar"))

4.无序表List

4.1 构造节点

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

4.2 链表实现无序表

class UnorderList:
    def __init__(self):
        self.head = None
    def add(self,newitem):
        temp = Node(newitem)
        temp.setNext(self.head)
        self.head = temp
    def size(self):
        current = self.head
        count = 0
        while current != None:
            count += 1
            curent = 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())

5.有序表List

class OrderList:
    def __init__(self):
        self.head = None
    def Search(self,item):
        current = self.head
        found = False
        stop = False
        while current != None and not found and not stop:
            if current.getData() == item:
                found = True
            else:
                if current.getData() > item:
                    stop = True
                else:
                    current = current.getNext()
        return found
    def add(self,item):
        current = self.head
        previous = None
        stop = False
        while current != None and not stop:
            if current.getData() > item:
                stop = True
            else:
                previous = current
                current = current.getNext()
        temp = Node(item)
        if previous == Node:
            temp.setNext(self.head)
            self.head = temp
        else:
            temp.setNext(current)
            previous.setNext(temp)
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值