栈,队列及哈希

栈,队列及哈希

一.如何实现栈

1.数组实现

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

    def isEmpty(self):
        return len(self.items)==0

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

    def top(self):
        if not self.isEmpty():
            return self.items[len(self.items)-1]
        else:
            return None

    def pop(self):
        if len(self.items)>0:
            return self.items.pop()
        else:
            print("栈已经为空")
            return None

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

if __name__=="__main__":
    stack=MyStack()
    stack.push(4)
    stack.push(3)
    print("栈顶元素为:",stack.top())
    print("栈大小为:",stack.size())
    stack.pop()
    print("栈顶元素为:", stack.top())
栈顶元素为: 3
栈大小为: 2
栈顶元素为: 4

2.链表实现

class LNode(object):
    def __init__(self,data):
        self.data=data
        self.next=None

class MyStack(object):
    def __init__(self):
        self.data=None
        self.next=None

    def empty(self):
        if self.next==None:
            return True
        else:
            return False

    def size(self):
        size=0
        p=self.next
        while p!=None:
            p=p.next
            size+=1
        return size

    def push(self,e):
        p=LNode(e)
        p.next=self.next
        self.next=p

    def pop(self):
        tmp=self.next
        if tmp!=None:
            self.next=tmp.next
            return tmp.data
        print("栈已经为空")
        return None

    def top(self):
        if self.next!=None:
            return self.next.data
        print("栈已经为空")
        return None

if __name__=="__main__":
    stack=MyStack()
    stack.push(1)
    print("栈顶元素为:",stack.top())
    print("栈大小为:",stack.size())
    print(stack.pop())
    stack.pop()
栈顶元素为: 1
栈大小为: 1
1
栈已经为空

算法性能分析:两种方法压栈与弹栈的时间复杂度都为O(1)

二.如何实现队列

1.数组实现

class MyQueue(object):
    def __init__(self):
        self.arr=[]
        self.front=0
        self.rear=0

    def isEmpty(self):
        return self.front==self.rear

    def size(self):
        return self.rear-self.front

    def getFront(self):
        if self.isEmpty():
            return None
        return self.arr[self.front]

    def getBack(self):
        if self.isEmpty():
            return None
        return self.arr[self.rear-1]

    def deQueue(self):
        if self.rear>self.front:
            self.front+=1
        else:
            print("队列已经为空")

    def enQueue(self,item):
        self.arr.append(item)
        self.rear+=1

if __name__=="__main__":
    queue=MyQueue()
    queue.enQueue(1)
    queue.enQueue(2)
    print("队列头元素为:",queue.getFront())
    print("队列尾元素为:",queue.getBack())
    print("队列大小为:",queue.size())
队列头元素为: 1
队列尾元素为: 2
队列大小为: 2

2.链表实现

class LNode(object):
    def __init__(self,data):
        self.data=data
        self.next=None

class MyQueue(object):
    def __init__(self):
        self.pHead=None
        self.pEnd=None

    def empty(self):
        if self.pHead==None:
            return True
        else:
            return False

    def size(self):
        size=0
        p=self.pHead
        while p!=None:
            p=p.next
            size+=1
        return size

    def enQueue(self,e):
        p=LNode(e)

        if self.pHead==None:
            self.pHead=self.pEnd=p
        else:
            self.pEnd.next=p
            self.pEnd=p

    def deQueue(self):
        if self.pHead==None:
            print("出队列失败,队列已经为空")
        self.pHead=self.pHead.next
        if self.pHead==None:
            self.pEnd=None

    def getFront(self):
        if self.pHead==None:
            print("获取队列元素失败,队列已经为空")
            return None
        return self.pHead.data

    def getBack(self):
        if self.pEnd==None:
            print("获取队列尾元素失败,队列已经为空")
            return None
        return self.pEnd.data

if __name__=="__main__":
    queue=MyQueue()
    queue.enQueue(1)
    queue.enQueue(2)
    print("队列头元素为:",queue.getFront())
    print("队列尾元素为:",queue.getBack())
    queue.deQueue()
    print("队列大小为:",queue.size())
队列头元素为: 1
队列尾元素为: 2
队列大小为: 1

三.翻转栈的所有元素

翻转栈的所有元素,例如输入栈[1,2,3,4,5],其中1处在栈顶,翻转之后的栈为[5,4,3,2,1],其中5处在栈顶

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

    def empty(self):
        return len(self.items)==0

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

    def peek(self):
        if not self.empty():
            return self.items[len(self.items)-1]
        else:
            return None

    def pop(self):
        if len(self.items)>0:
            return self.items.pop()
        else:
            print("栈已经为空")
            return None

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

def moveBottomToTop(s):
    if s.empty():
        return

    top1=s.peek()
    s.pop()
    if not s.empty():
        moveBottomToTop(s)
        top2=s.peek()
        s.pop()

        s.push(top1)
        s.push(top2)
    else:
        s.push(top1)


def reverse_stack(s):
    if s.empty():
        return

    moveBottomToTop(s)
    top=s.peek()
    s.pop()
    reverse_stack(s)
    s.push(top)

if __name__=="__main__":
    stack=Stack()
    stack.push(5)
    stack.push(4)
    stack.push(3)
    stack.push(2)
    stack.push(1)
    reverse_stack(stack)
    print("翻转后的出栈顺序为:")
    while not stack.empty():
        print(stack.peek(),end=" ")
        stack.pop()
翻转后的出栈顺序为:
5 4 3 2 1

算法性能分析:翻转算法的时间复杂度为O(N^2)

四.根据入栈序列判断可能的出栈序列

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

    def empty(self):
        return len(self.items)==0

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

    def peek(self):
        if not self.empty():
            return self.items[len(self.items)-1]
        else:
            return None

    def pop(self):
        if len(self.items)>0:
            return self.items.pop()
        else:
            print("栈已经为空")
            return None

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

def isPopSerial(push,pop):
    if push==None or pop==None:
        return False

    pushLen=len(push)
    popLen=len(pop)

    if pushLen!=popLen:
        return False

    pushIndex=0
    popIndex=0
    stack=Stack()

    while pushIndex<pushLen:
        stack.push(push[pushIndex])
        pushIndex+=1

        while not stack.empty() and stack.peek()==pop[popIndex]:
            stack.pop()
            popIndex+=1

    return stack.empty() and popIndex==popLen

if __name__=="__main__":
    push="12345"
    pop="32541"

    if isPopSerial(push,pop):
        print(pop+"是"+push+"的一个pop序列")
    else:
        print(pop+"不是"+push+"的一个pop序列")
32541是12345的一个pop序列

算法性能分析:时间复杂度为O(n),空间复杂度为O(n)

五.用O(1)的时间复杂度求栈中最小元素

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

    def empty(self):
        return len(self.items)==0

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

    def peek(self):
        if not self.empty():
            return self.items[len(self.items)-1]
        else:
            return None

    def pop(self):
        if len(self.items)>0:
            return self.items.pop()
        else:
            print("栈已经为空")
            return None

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


class MyStack(object):
    def __init__(self):
        self.elemStack=Stack()
        self.minStack=Stack()

    def push(self,data):
        self.elemStack.push(data)

        if self.minStack.empty():
            self.minStack.push(data)
        else:
            if data<self.minStack.peek():
                self.minStack.push(data)

    def pop(self):
        topData=self.elemStack.peek()
        self.elemStack.pop()
        if topData==self.mins():
            self.minStack.pop()
        return topData

    def mins(self):
        if self.minStack.empty():
            return None
        else:
            return self.minStack.peek()



if __name__=="__main__":
    stack=MyStack()
    stack.push(5)
    print("栈中最小值为:",stack.mins())
    stack.push(6)
    print("栈中最小值为:", stack.mins())
    stack.push(2)
    print("栈中最小值为:", stack.mins())
    stack.pop()
    print("栈中最小值为:", stack.mins())
栈中最小值为: 5
栈中最小值为: 5
栈中最小值为: 2
栈中最小值为: 5

算法性能分析:时间复杂度为O(1),空间复杂度为O(n)

六.用两个栈模拟队列操作

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

    def empty(self):
        return len(self.items)==0

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

    def peek(self):
        if not self.empty():
            return self.items[len(self.items)-1]
        else:
            return None

    def pop(self):
        if len(self.items)>0:
            return self.items.pop()
        else:
            print("栈已经为空")
            return None

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


class MyStack(object):
    def __init__(self):
        self.A=Stack()
        self.B=Stack()
        
    def push(self,data):
        self.A.push(data)
        
    def pop(self):
        if self.B.empty():
            while not self.A.empty():
                self.B.push(self.A.peek())
                self.A.pop()
        
        first=self.B.peek()
        self.B.pop()
        return first
    
if __name__=="__main__":
    stack=MyStack()
    stack.push(1)
    stack.push(2)
    print("队列首元素为:",stack.pop())
    print("队列首元素为:", stack.pop())
队列首元素为: 1
队列首元素为: 2

七.设计一个排序系统

from collections import deque

class User:
    def __init__(self,id,name):
        self.id=id
        self.name=name
        self.seq=0

    def getName(self):
        return self.name

    def setName(self,name):
        self.name=name

    def getSeq(self):
        return self.seq

    def setSeq(self,seq):
        self.seq=seq

    def getId(self):
        return self.id

    def equals(self,arg0):
        o=arg0
        return self.id==o.getId()

    def toString(self):
        return "id:"+str(self.id)+"name:"+self.name+"seq:"+str(self.seq)


class MyQueue:
    def __init__(self):
        self.q=deque()

    def enQueue(self,u):
        u.setSeq(len(self.q)+1)
        self.q.append(u)

    def deQueue(self):
        self.q.popleft()
        self.updateSeq()

    def deQueuemove(self,u):
        self.q.remove(u)
        self.updateSeq()

    def updateSeq(self):
        i=1
        for u in self.q:
            u.setSeq(i)
            i+=1

    def printList(self):
        for u in self.q:
            print(u.toString())


if __name__=="__main__":
    u1=User(1,"user1")
    u2=User(2,"user2")
    u3=User(3,"user3")
    u4=User(4,"user4")

    queue=MyQueue()
    queue.enQueue(u1)
    queue.enQueue(u2)
    queue.enQueue(u3)
    queue.enQueue(u4)
    queue.printList()
    queue.deQueue()
    queue.deQueuemove(u3)
    print("用户1和3出队后:")
    queue.printList()
id:1name:user1seq:1
id:2name:user2seq:2
id:3name:user3seq:3
id:4name:user4seq:4
用户1和3出队后:
id:2name:user2seq:1
id:4name:user4seq:2

八.实现LRU缓存方案

from collections import deque

class LRU:
    def __init__(self,cacheSize):
        self.cacheSize=cacheSize
        self.queue=deque()
        self.hashSet=set()

    def isQueueFull(self):
        return len(self.queue)==self.cacheSize

    def enqueue(self,pageNum):
        if self.isQueueFull():
            self.hashSet.remove(self.queue[-1])
            self.queue.pop()

        self.queue.appendleft(pageNum)
        self.hashSet.add(pageNum)

    def accessPage(self,pageNum):
        if pageNum not in self.hashSet:
            self.enqueue(pageNum)
        elif pageNum!=self.queue[0]:
            self.queue.remove(pageNum)
            self.queue.appendleft(pageNum)

    def printQueue(self):
        while len(self.queue)>0:
            print(self.queue.popleft())

if __name__=="__main__":
    lru=LRU(3)

    lru.accessPage(1)
    lru.accessPage(2)
    lru.accessPage(5)
    lru.accessPage(1)
    lru.accessPage(6)
    lru.accessPage(7)

    lru.printQueue()
7
6
1

九.从给定的车票中找出旅程

def PrintResult(inputs):
    reverseInput=dict()

    for k,w in inputs.items():
        reverseInput[w]=k

    start=None

    for k,w in inputs.items():
        if k not in reverseInput:
            start=k
            break

    if start==None:
        print("输入不合理")
        return

    to=inputs[start]
    print(start+"-->"+to,end=",")
    start=to
    to=inputs[to]
    while to!=None:
        print(start+"-->"+to,end=",")
        start=to
        to=inputs[to]

if __name__=="__main__":
    inputs=dict()
    inputs["西安"]="成都"
    inputs["北京"]="上海"
    inputs["大连"]="西安"
    inputs["上海"]="大连"

    PrintResult(inputs)

十.在数组中找出满足a+b=c+d的两个数对

class pair:
    def __init__(self,first,second):
        self.first=first
        self.second=second


def findPairs(arr):
    sumPair=dict()
    n=len(arr)

    i=0
    while i<n:
        j=i+1
        while j<n:
            sums=arr[i]+arr[j]
            if sums not in sumPair:
                sumPair[sums]=pair(i,j)
            else:
                p=sumPair[sums]
                print("(%d,%d),(%d,%d)"%(arr[p.first],arr[p.second],arr[i],arr[j]))
                return True
            j+=1
        i+=1
    return False

if __name__=="__main__":
    arr=[3,4,7,10,20,9,8]
    findPairs(arr)
(3,8),(4,7)
原文地址:https://www.cnblogs.com/LQ6H/p/12940548.html