数据结构与算法----栈和队列(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


总结


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

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

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


相关文章
|
15天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
90 9
|
1月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
62 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
1月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
30 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
18天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
初步认识栈和队列
初步认识栈和队列
58 10
|
1月前
【数据结构】-- 栈和队列
【数据结构】-- 栈和队列
16 0
|
1月前
探索数据结构:队列的的实现与应用
探索数据结构:队列的的实现与应用
|
1月前
|
存储 C语言
栈和队列题目练习
栈和队列题目练习
16 0
|
6天前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
15 1
|
9天前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。