zoukankan      html  css  js  c++  java
  • 队列

    一、什么是队列

    队列(Queue):具有一定操作约束的线性表

    • 插入和删除操作:只能在一端插入,而在另一端删除

    • 数据插入:入队列(AddQ)

    • 数据删除:出队列(DeleteQ)

    • 先来先去服务

    • 先进先出: (FIFO)

    二、队列的抽象数据类型描述

    类型名称:队列((Queue)

    数据对象集:一个有(0)个或多个元素的有穷线性表。

    操作集:长度为(MaxSize)的队列(Qin{Queue}),队列元素(itemin{ElementType})

    1. Queue CreateQueue(int MaxSize):生成长度为(MaxSize)的空队列;
    2. int IsFullQ(Queue Q, int MaxSize):判断队列(Q)是否已满;**
    3. void AddQ(Queue Q, ElementType item):将数据元素(item)插入队列(Q)中;
    4. int IsEmptyQ(Queue Q):判断队列(Q)是否为空;**
    5. ElementType DeleteQ(Queue Q):将队头数据元素从队列中删除并返回。

    三、队列的顺序存储实现

    队列的顺序存储结构通常由一个一维数组和一个记录队列头元素位置的变量front以及一个记录队列尾元素的变量rear组成。

    /* c语言实现 */
    
    #define MaxSize <储存数据元素的最大个数>
    struct QNode{
      ElementType Data[MaxSize];
      int rear;
      int front;
    };
    typedef struct QNode *Queue;
    

    例:一个工作队列

    四、循环队列

    思考:

    1. 上述这种循环队列的方案:堆栈空和满的判别条件是什么?
    2. 为什么会出现空、满无法区分?根本原因是什么?

    解决方案:

    1. 使用额外标记:(Size)或者(tag)
    2. 仅使用(n-1)个数组空间

    4.1 入队列

    Frontrear指针的移动采用“加1取余”法,体现了顺序存储的“循环使用”。

    /* c语言实现 */
    
    void AddQ(Queue PtrQ, ElementType item)
    {
      if ((PtrQ->rear + 1) % MaxSize == PtrQ->front){
        printf("队列满");
        return ;
      }
      PtrQ->rear = (PtrQ->rear+1) % MaxSize;
      PtrQ->Data[PtrQ->rear] = item;
    }
    

    4.2 出队列

    /* c语言实现 */
    
    ElementType DeleteQ(Queue PtrQ)
    {
      if (PtrQ->front = PtrQ->rear){
        printf("队列空");
        return ERROR;
      } else {
        PtrQ->front = (PtrQ->front + 1) % MaxSize;
        return PtrQ->Data[PtrQ->front];
      }
    }
    

    五、队列的链式存储实现

    队列的链式存储结构也可以用一个单链表实现。插入和删除操作分别在链表的两头进行;队列指针front应该在链表的头部;rear应该在链表的尾部。因为front在链表的尾部,删除操作后找不到上一个元素。

    /* c语言实现 */
    
    struct Node{
      ElementType Data;
      struct Node *Next;
    }
    struct QNode{ /* 链队列结构 */
      struct Node *rear; /* 指向队尾结点 */
      struct Node *front; /* 指向队头结点 */
    };
    typedef struct QNode *Queue;
    Queue PtrQ;
    

    5.1 出队列

    不带头结点的链式队列出队操作的一个示例:

    /* c语言实现 */
    
    ElementType DeleteQ(Queue PtrQ)
    {
      struct Node *FrontCell;
      ElementType FrontElem;
      
      if (PtrQ->front == NULL){
        printf("队列空"); return ERROR;
      }
      FrontCell = PtrQ->front;
      if (PtrQ->front == PtrQ->rear) /* 若队列只有一个元素 */
        PtrQ->front = PtrQ->rear = NULL; /* 删除后对列置为空 */
      else
        PtrQ->front = PtrQ->front->Next;
      FrontElem = FrontCell->Data;
      free(FrontCell); /* 释放被删除结点空间 */
      return FrontElem;
    }
    

    六、Python实现-队列

    # python语言实现
    
    class Head(object):
        def __init__(self):
            self.left = None
            self.right = None
    
    
    class Node(object):
        def __init__(self, value):
            self.value = value
            self.next = None
    
    
    class Queue(object):
        def __init__(self):
            # 初始化节点
            self.head = Head()
    
        def enqueue(self, value):
            # 插入一个元素
            newnode = Node(value)
            p = self.head
            if p.right:
                # 如果head节点的右边不为None
                # 说明队列中已经有元素了
                # 就执行下列的操作
                temp = p.right
                p.right = newnode
                temp.next = newnode
            else:
                # 这说明队列为空,插入第一个元素
                p.right = newnode
                p.left = newnode
    
        def dequeue(self):
            # 取出一个元素
            p = self.head
            if p.left and (p.left == p.right):
                # 说明队列中已经有元素
                # 但是这是最后一个元素
                temp = p.left
                p.left = p.right = None
                return temp.value
            elif p.left and (p.left != p.right):
                # 说明队列中有元素,而且不止一个
                temp = p.left
                p.left = temp.next
                return temp.value
    
            else:
                # 说明队列为空
                # 抛出查询错误
                raise LookupError('queue is empty!')
    
        def is_empty(self):
            if self.head.left:
                return False
            else:
                return True
    
        def top(self):
            # 查询目前队列中最早入队的元素
            if self.head.left:
                return self.head.left.value
            else:
                raise LookupError('queue is empty!')
    
  • 相关阅读:
    366. Find Leaves of Binary Tree输出层数相同的叶子节点
    716. Max Stack实现一个最大stack
    515. Find Largest Value in Each Tree Row查找一行中的最大值
    364. Nested List Weight Sum II 大小反向的括号加权求和
    156. Binary Tree Upside Down反转二叉树
    698. Partition to K Equal Sum Subsets 数组分成和相同的k组
    244. Shortest Word Distance II 实现数组中的最短距离单词
    187. Repeated DNA Sequences重复的DNA子串序列
    java之hibernate之基于主键的双向一对一关联映射
    java之hibernate之基于主键的单向一对一关联映射
  • 原文地址:https://www.cnblogs.com/nickchen121/p/11439674.html
Copyright © 2011-2022 走看看