一、物理结构和逻辑结构
- 物理结构就是看得见,摸得着。而数组和链表,就是内存中实实在在的存储结构。
- 逻辑结构就是看不见、摸不着。
二、 栈(stack)
栈(stack)是一种线性数据结构,栈中的元素只能先进后出 (First In Last Out,简称FILO)。最早进入的元素存放的位置叫作栈底(bottom),最后进入的元素存放的位置叫作栈顶(top)。
栈这种数据结构既可以用数组来实现,也可以用链表来实现。
栈的基本操作
1.入栈
入栈操作(push)就是把新元素放入栈中,只允许从栈顶一侧放入元素,新元素的位置将会成为新的栈顶。
2.出栈
出栈操作(pop)就是把元素从栈中弹出,只有栈顶元素才允许出栈,出栈元素的前一个元素将会成为新的栈顶。
在Python语言中,列表很好地实现了栈的功能,append方法相当于入栈,pop方法相当于出栈。由于栈操作的代码实现相对简单。
ll=[1,2,3,4,5,6]
#入栈
ll.append(50)
ll.append(60)
print(ll)
#出栈第一个
ll.pop(0)
#出栈最后一个
ll.pop(len(ll)-1)
print(ll)
四、队列
队列(queue)是一种线性数据结构,队列中的元素只能先进先出(First In First Out,简称FIFO)。队列的出口端叫作队头(front),队列的入口端叫作队尾( rear) 。
与栈类似,队列这种数据结构既可以用数组来实现,也可以用链表来实现。
队列的基本操作
1、入队
入队( enqueue)就是把新元素放入队列中,只允许在队尾的位置放入元素,新元素的下一个位置将会成为新的队尾。
2、出队
出队操作(dequeue)就是把元素移出队列,只允许在队头一侧移出元素,出队元素的后一个元素将会成为新的队头。
如果不断出队,队头左边的空间失去作用,那队列的容量岂不是越来越小?
那么就使用数组实现的队列可以采用循环队列的方式来维持队列容量的恒定。
一直到(队尾下标+1)%数组长度=队头下标时,代表此队列真的已经满了。需要注意的是,队尾指针指向的位置永远空出1位,所以队列最大容量比数组长度小1。
#用列表实现循环队列
class MyQueue:
'''初始化'''
def __init__(self, capacity):
self.list = [None] * capacity #队列长度
self.head = 0 #头指针
self.tail = 0 #尾指针
#入队操作
def enqueue(self, element):
#循环队列判断队列是否满
if (self.tail + 1) % len(self.list) == self.head:
raise Exception("队列已满")
self.list[self.tail] = element
self.tail = (self.tail + 1) % len(self.list)
#出队操作
def dequeue(self):
#循环队列判断队列是否为空,如果为空。
if self.tail == self.head:
raise Exception("队列为空")
dequeue_element = self.list[self.head]
self.head = (self.head + 1) % len(self.list)
return dequeue_element
#打印循环队列内的元素
def show(self):
i = self.head #队头
while i is not self.tail:
print(self.list[i],end="\t")
i = (i + 1) % len(self.list)
(1)入队已满
if __name__ == '__main__':
#队列对象
myQueue = MyQueue(3)
#入队
myQueue.enqueue(3)
myQueue.enqueue(4)
myQueue.enqueue(5)
myQueue.enqueue(6)
(2) 入队,再出队OK
if __name__ == '__main__':
#队列对象
myQueue = MyQueue(6)
#入队
myQueue.enqueue(3)
myQueue.enqueue(4)
myQueue.enqueue(5)
myQueue.enqueue(6)
#出队
print(myQueue.dequeue())
print(myQueue.dequeue())
print('*'*20)
(3) 入队,再出队,队列为空
if __name__ == '__main__':
#队列对象
myQueue = MyQueue(6)
#入队
myQueue.enqueue(3)
#出队
print(myQueue.dequeue())
print(myQueue.dequeue())
(4) 入队,再出队
if __name__ == '__main__':
#队列对象
myQueue = MyQueue(6)
#入队
myQueue.enqueue(3)
myQueue.enqueue(4)
myQueue.enqueue(5)
myQueue.enqueue(6)
#出队
print(myQueue.dequeue())
print(myQueue.dequeue())
print('*'*20)
#再入队
myQueue.enqueue(10)
myQueue.enqueue(20)
#显示
myQueue.show()
总之:入队和出队的时间复杂度,也同样是O (1)