栈,队列及哈希
一.如何实现栈
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)