数据结构与算法----栈和队列(Stack & Queue)(三)

简介: 数据结构与算法----栈和队列(Stack & Queue)

队列


队列是一种运算受限的线性表,元素的添加操作在表的一端进行,而另一端的删除在另一端进行,允许插入的一端称为队尾,允许删除的一端称为队头。


假设队列 q = [x1,x2,x3,,,,,xn] x1是队头,x2是队尾,队列中的数据的入队序列是x1,x2,x3,,,xn,队列也只能按这个顺序进行出队,队列的特点是先进入队列的先出来,后进队的必须等前面的数据出队完成以后才可以出队,所以队列也成为先进先出表(First in First out)


84b385e584a447edb91104a048d67b8c.png

队列的操作


队列由由多种实现方式,这里就选三个比较有代表性的实现方式讲解’基础队列,循环队列链队列,代码放在后面,在讲解的途中就在分别展示了


说明:循环队列也是用数组来实现的,只不过通过,一些算法实现了数组空间的复用,而且不用频繁的移动数组中的元素。


初始化队列


22da93f192624398b21f91a5c26e1735.png


入队


e4cd8d39755c443f965f7faa13e5b7d8.png


出队


原队列


ae761914d70e403f81cf5dcfd971db49.png



出队


顺序队列:就是将第一个元素返回出去,其余的元素向前移动一单位

循环队列:就是将队头的指针向后移动一个单位,里面的元素变为无效数据,等待覆盖

链队列:就是链表的删除,将头部指针front,指向队头的的指针移动到,指向队头后一个元素


a11cc399eaf1437eba0f29f864258233.png


遍历队列


顺序队列:将数组中的中的数据从开头一直遍历到最后

循环队列:创建一个临时的指针tmp该指针的位置和front指针一样,根据这个临时指针tmp的移动一次访问元素,直至临时指针和rear指针指向同一个位置的时候停止。

链队列:从头部直接遍历,循环调用next方法,直至到next==null的时候停止遍历


清空队列


清空队列就是将队列中的所有元素清空,让队列回归最初的状态


顺序队列:清空列表中的元素,并将rear指针回归到最初的位置

循环队列:清空列表中的元素,并将指针回归到最初的位置

链队列:将头部指针指向为null


队列的存储结构


顺序存储


基础队列的队头始终在数组的头部,每删除一个元素,整个队列就会向前移动一个单位,保证队列头始终在数组的第一个元素。这样我门就可以发现每执行删除操作(出队),队列就要移动一次,这样会造成系统的额外开销。


class BaseQueue:
    def __init__(self):
        self.data = []
        self.front = 0
        self.rear = 0  # 记录队尾
        self.maxlength = 10  # 设置队列的最大长度
    def enqueue(self, arg):
        """入队"""
        if self.rear >= self.maxlength:
            print("队列已满")
            return
        self.rear += 1
        self.data.append(arg)
    def dequeue(self):
        """出队"""
        if self.rear == 0:
            print("队列已空")
            return
        self.rear -= 1
        return self.data.pop(0)
    def gethead(self):
        """获取队头"""
        if self.rear == 0:
            print("队列已空")
            return
        return self.data[0]
    def size(self):
        """返回队列的长度"""
        return self.rear
    def isEmpty(self):
        """判断队列是否为空"""
        return self.rear == 0
    def next(self):
        """遍历并输出"""
        p = self.rear
        for i in range(0, p):
            print(self.data[i])
    def clear(self):
        """清空队列"""
        self.data.clear()
        self.rear = 0


循环队列


循环队列,本质上还是使用数组进行实现,只是在逻辑上将首部、尾部连接起来,形成一个环状的循环队列,循环队列存储的元素个数比数组的长度少一,用来区分队满还是对待队空。


class LoopQueue:
    def __init__(self):
        self.maxsize = 10
        self.data = [0 for i in range(self.maxsize)]
        self.front = 0
        self.rear = 0
    def enqueue(self, arg):
        """入队"""
        if (self.rear + 1) % self.maxsize == self.front:
            print("队列已满,无法入队")
            return
        self.data[self.rear] = arg
        self.rear = (self.rear + 1) % self.maxsize
    def dequeue(self):
        """出队"""
        if self.isEmpty():
            print("队列已空,无法读取元素")
            return
        tmp = self.data[self.front]
        self.front = self.front + 1 % self.maxsize
        return tmp
    def gethead(self):
        """获取队头"""
        if self.isEmpty():
            print("队列已空,无法读取元素")
            return
        tmp = self.data[self.front]
        return tmp
    def size(self):
        """返回队列的长度"""
        if self.front <= self.rear:
            return self.rear - self.front
        else:
            return self.maxsize - (self.front - self.rear)
    def isEmpty(self):
        """判断队列是否为空"""
        return self.front == self.rear
    def next(self):
        """遍历并输出"""
        tmp = self.front
        while tmp < self.rear:
            print(self.data[tmp])
            tmp += 1
    def clear(self):
        """清空队列"""
        self.front = 0
        self.rear = 0


链式存储


队列的链存储结构称为链队列,它是限制在表头删除和表尾插入的单链表,由于需要在表尾进行插入操作,所以为操作方便除头指针外有必要再增加一个指向尾节点的指针

这个部分用到的链表的知识比较多,如果有不理解的可以去补补链表的知识


class Node(object):
    """节点类"""
    def __init__(self, data=None):
        self.data = data
        self.next = None
class LinkQueue:
    def __init__(self):
        self.length = 0
        self.front = None  # 头节点
        self.rear = None  # 尾节点
    def enqueue(self, arg):
        """入队"""
        node = Node(data=arg)
        if self.isEmpty():
            self.front = self.rear = node
            self.length += 1
        else:
            self.rear.next = node
            self.rear = node
            self.length += 1
    def dequeue(self):
        """出队"""
        if self.isEmpty():
            print("队列为空")
        else:
            resulst = self.front.data
            self.front = self.front.next
            self.length-=1
            return resulst
    def gethead(self):
        """获取队头"""
        if not self.isEmpty():
            return self.front.data
        else:
            print("队列为空")
    def size(self):
        """返回队列的长度"""
        return self.length
    def isEmpty(self):
        """判断队列是否为空"""
        if self.length == 0:
            return True
        else:
            return False
    def next(self):
        """遍历并输出"""
        tmp = self.front
        while tmp:
            print(tmp.data)
            tmp = tmp.next
    def clear(self):
        """清空队列"""
        self.front = None
        self.rear = None


队列实战题目


这两个题目我们再刚开始讲解的时候已经写过了


78ae94c602c34bc2b7a1b864404304d6.png


总结


栈是限定再表尾进行插入或删除的线性表,又称后进先出的线性表,栈有两种存储表示,顺序栈,链式栈,链的主要操作是进栈和出栈,对于出栈和进栈操作判断栈满还是栈空

队列是一种先进先出的线性表,它只允许在表的一端进行插入,而在另一端进行删除,队列也有两种存储结构,顺序存储,链式存储,队列的主要操作是进队和出队,对于顺序表需要注意队满和队空的情况

栈和队列是在程序设计中被广泛使用的两种数据结构,其具体的应用场景都是与其展示方法和运算规则相互关联的。


相关文章
|
18小时前
|
算法
【算法】栈
栈相关算法题,供参考,附有链接地址及板书
|
2月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
86 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
2月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
48 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
1月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
2月前
|
算法
数据结构与算法二:栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式
这篇文章讲解了栈的基本概念及其应用,并详细介绍了中缀表达式转换为后缀表达式的算法和实现步骤。
68 3
|
2月前
|
算法 Java API
【用Java学习数据结构系列】对象的比较(Priority Queue实现的前提)
【用Java学习数据结构系列】对象的比较(Priority Queue实现的前提)
34 1
|
2月前
|
C语言
数据结构------栈(Stack)和队列(Queue)
数据结构------栈(Stack)和队列(Queue)
25 0
|
2月前
|
算法 C++
【算法单调栈】 矩形牛棚(C/C++)
【算法单调栈】 矩形牛棚(C/C++)
|
4月前
|
算法
【算法】栈算法——逆波兰表达式求值
【算法】栈算法——逆波兰表达式求值
|
2月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
94 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。