python:链表和顺序表实现队列类

#【队列】
# 队列(queue)也是一种容器,可存入元素、访问元素、删除元素。

# 队列抽象数据类型】
'''
ADT Queue:
    Queue(self)           #  创建空队列
    is_empty(self)        #  判断队列是否为空,空时返回True,否则返回False
    enqueue(self,elem)    #  将元素elem加入队列,常称--入队
    dequeue(self)         #  删除队列里最早进入的元素并将其返回,常称--出队
    peek(self)            #  查看队列里最早进入的元素,不删除   

'''

#  队列的链结表实现】
class LQueue_Err(ValueError):
    pass
class Node:                           #   简单结点类
    def __init__(self,elem,next_ = None):
        self.elem = elem
        self.next = next_

class LQueue:
    def __init__(self):
        self._head = None
        self._rear = None              #  最后一个元素的链接
    def is_empty(self):
        return self._head is None     #  为空时,返回True
    def enqueue(self,elem):            #  入队--后端加入元素
        if self._head is None:
            self._head = Node(elem)
            self._rear = self._head
        else:
            self._rear.next = Node(elem)
            self._rear = self._rear.next
    def dequeue(self):                  #  出队--前端删除元素
        if self._head is None:
            raise LQueue_Err("Error in LQueue.dequeue")
        else:
            p =self._head
            self._head = self._head.next
            return p.elem
    def peek(self):                    #  查看队列里最早进入的元素
        if self._head is None:
            raise LQueue_Err("Error in LQueue.peek")
        else:
            return self._head.elem



#  队列的顺序表实现】
'''
1. _elems 属性 --队列的元素存储区,是一个list对象,
   _len   属性 --记录储存区域的的有效容量。
2. _head  属性 --是队列中首元素的下标(队列中最早存入的那个元素),
   _num   属性 --始终记录着队列中元素的个数。
3. 队列中的元素总保存在_elems里从_head开始的连续位置中,
   新入队的元素存入由 _head + _num 算出的位置。
4. 在_num == _len 的情况下出现入队操作,就扩大存储区域。

队列的首元素在----self._elems[self._head](peek和dequeue操作应取这里的元素)
下一个空位在self._elems[(self._head +self._num)%self._len],入队的新元素应该在这里
队列空----self._num == 0
当前队列满---- self._num == self._len

'''
class QueueUderflow(ValueError):
    pass
class SQueue:
    def __init__(self, init_len=8):
        self._len = init_len                        #  储存区域的长度
        self._elems = [0]*init_len                  #  元素存储
        self._head = 0                              #  表头元素下标
        self._num = 0                               #  元素个数
    def is_empty(self):
        return self._num == 0
    def peek(self):
        if self._num == 0:
            raise QueueUderflow("Error in SQueue.peek")
        return self._elems[self._head]
    def dequeue(self):
        if self._num == 0:
            raise QueueUderflow("Error in SQueue.dequeue")
        e = self._elems[self._head]
        self._head = (self._head+1) % self._len
        self._num -= 1
        return e
    def enqueue(self,elem):
        if self._num == self._len:    #  队列满时,对其进行扩充
            self._extend_queue()
        self._elems[(self._head+self._num)%self._len] =elem
        self._num += 1
    def _extend_queue(self):          #  队列扩充函数
        old_len = self._len
        self._len *= 2
        new_elems = [0]*self._len
        for i in range(old_len):
            new_elems[i] = self._elems[(self._head+i) % old_len]
        self._elems, self._head = new_elems, 0


#  简单使用验证
bb = SQueue()
for i in range(1,15):
    bb.enqueue(i)
    print(i)

print(bb.is_empty())
print(bb.peek())

for i in range(1,15):
    print(bb.dequeue())
print(bb.is_empty())

猜你喜欢

转载自blog.csdn.net/weixin_39781462/article/details/82382348