数据结构-队列队列的基本操作

Posted Mount256

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构-队列队列的基本操作相关的知识,希望对你有一定的参考价值。

文章目录

1 顺序表实现队列(循环队列)

实现方式:

  • 队尾指针指向队尾元素
  • 队尾指针指向队尾元素的下一位置(队头指针在队尾指针的下一个位置作为队满标志

1.1 定义

  • 队尾指针指向队尾元素:
# define MAX 50 // 队列的容量

typedef struct Queue
    int data[MAX];
    int size; // 增设记录队列当前元素的个数
    int front, rear;
 Queue;
  • 队尾指针指向队尾元素的下一位置:
# define MAX 50 // 队列的容量

typedef struct Queue
    int data[MAX];
    int front, rear;
 Queue;

1.2 初始化

  • 队尾指针指向队尾元素:
void InitQueue (Queue &Q)
    Q.front = 0;
    Q.rear = MAX-1;
    Q.size = 0;

  • 队尾指针指向队尾元素的下一位置:
void InitQueue (Queue &Q)
    Q.front = 0;
    Q.rear = 0;

1.3 判队空

  • 队尾指针指向队尾元素:
bool EmptyQueue (Queue &Q)
    if (Q.size == 0)
        return true;
    else
        return false;

  • 队尾指针指向队尾元素的下一位置:
bool EmptyQueue (Queue &Q)
    if (Q.front == Q.rear)
        return true;
    else
        return false;

1.4 判队满

  • 队尾指针指向队尾元素:
bool FullQueue (Queue &Q)
    if (Q.size == MAX)
        return true;
    else
        return false;

  • 队尾指针指向队尾元素的下一位置:
bool FullQueue (Queue &Q)
    if ((Q.rear+1) % MAX == Q.front)
        return true;
    else
        return false;

1.5 出队

  • 队尾指针指向队尾元素:
bool DeQueue (Queue &Q, int &x)
    if (Q.size == 0)
        return false;
    
    x = Q.data[Q.front]; // 获得出队元素
    Q.front = (Q.front+1) % MAX; // 队头指针加 1
    return true;

  • 队尾指针指向队尾元素的下一位置:
bool DeQueue (Queue &Q, int &x)
    if (Q.front == Q.rear)
        return false;
    
    x = Q.data[Q.front]; // 获得出队元素
    Q.front = (Q.front+1) % MAX; // 队头指针加 1
    return true;

1.6 入队

  • 队尾指针指向队尾元素:
bool EnQueue (Queue &Q, const int x)
    if (Q.size == MAX)
        return false;
    
    Q.rear = (Q.rear+1) % MAX; // 队尾指针加 1
    Q.data[Q.rear] = x; // 入队
    return true;

  • 队尾指针指向队尾元素的下一位置:
bool EnQueue (Queue &Q, const int x)
    if ((Q.rear+1) % MAX == Q.front)
        return false;
    
    Q.data[Q.rear] = x; // 入队
    Q.rear = (Q.rear+1) % MAX; // 队尾指针指向下一个位置
    return true;

1.7 队长

int LenQueue (Queue &Q)
    return (Q.rear - Q.front + MAX) % MAX;

2 单向链表实现队列

单向链表实现队列:链表头出队,链表尾入队。

实现方式:

  • 不带头结点
  • 带头结点(头结点可存储当前队列的元素个数

2.1 定义

  • 不带头结点:
#define MAX 50 // 队列的容量

typedef struct LinkNode
    int data;
    struct LinkNode *next;
LinkNode;

typedef struct Queue
    int size; // 增设记录队列当前元素的个数
    struct LinkNode *front;
    struct LinkNode *rear;
LinkQueue;
  • 带头结点:
#define MAX 50 // 队列的容量

typedef struct LinkNode
    int data;
    struct LinkNode *next;
LinkNode;

typedef struct Queue
    // struct LinkNode *front; // 队头指针可由头结点指针充当实现
    struct LinkNode *rear;
    struct LinkNode *head; // 头结点指针
LinkQueue;

2.2 初始化

  • 不带头结点:
void InitQueue (LinkQueue &Q)
    Q.front = NULL;
    Q.rear = NULL;
    Q.size = 0;

  • 带头结点:
void InitQueue (LinkQueue &Q)
    Q.head = (LinkNode *) malloc(sizeof(LinkNode)); // 创建头结点
    Q.rear = Q.head; // 初始时,队头指针和队尾指针指向头结点
    Q.head->data = 0; // 记录队列当前元素个数
    Q.head->next = NULL;

2.3 判队空

  • 不带头结点:
bool EmptyQueue (LinkQueue &Q)
    if ((Q.front == NULL) || (Q.rear == NULL))
        return true;
    else
        return false;

bool EmptyQueue (LinkQueue &Q)
    if (Q.size == 0)
        return true;
    else
        return false;

  • 带头结点:
bool EmptyQueue (LinkQueue &Q)
    if (Q.head->data == 0)
        return true;
    else
        return false;

bool EmptyQueue (LinkQueue &Q)
    if (Q.head == Q.rear)
        return true;
    else
        return false;

2.4 判队满

  • 不带头结点:
bool FullQueue (LinkQueue &Q)
    if (Q.size == MAX)
        return true;
    else
        return false;

  • 带头结点:
bool FullQueue (LinkQueue &Q)
    if (Q.head->data == MAX)
        return true;
    else
        return false;

2.5 出队

  • 不带头结点:
bool DeQueue (LinkQueue &Q, int &x)
    LinkNode *frontNext; // 记录队头指针的下一个结点

    if ((Q.front == NULL) || (Q.rear == NULL)) // 判空,或:Q.size == 0
        return false;
        
    x = Q.front->data;
    
    if (Q.front == Q.rear) // 若队列只有一个结点
        free(Q.front);
        Q.front = NULL;
        Q.rear = NULL;
    
    else 
        frontNext = Q.front->next; // 记录队头指针的下一个结点
        free(Q.front);
        Q.front = frontNext; // 更新队头指针
    
    
    Q.size--; // 出队,减少一个元素
    return true;

  • 带头结点:
bool DeQueue (LinkQueue &Q, int &x)
    LinkNode *front = Q.head->next; // 队头指针

    if (Q.head == Q.rear) // 判空,或:Q.head->data == 0
        return false;
        
    x = front->data;
    
    Q.head->data--; // 出队,减少一个元素
    Q.head->next = front->next; // 头结点的指针域指向队头结点的下一个结点
    if (front == Q.rear) // 若队列只有一个结点,出队后只剩头结点
        Q.rear = Q.head; // 队尾指针指向头结点
    free(front);
    return true;

2.6 入队

  • 不带头结点:
bool EnQueue (LinkQueue &Q, const int x)
    LinkNode *newNode;

    if (Q.size == NUM) // 判满
        return false;
        
    newNode = (LinkNode *) malloc(sizeof(LinkNode));
    newNode->data = x;
    newNode->next = NULL;
    
    if ((Q.front == NULL) || (Q.rear == NULL)) // 如果队列为空 // 或:Q.size == 0
        Q.front = newNode;
        Q.rear = newNode;
    
    else
        Q.rear->next = newNode; // 队尾指针的指针域指向新结点
        Q.rear = newNode; // 队尾指针指向新结点
    
    
    Q.size++; // 入队,增加一个元素
    return true;

  • 带头结点:
bool EnQueue (LinkQueue &Q, const int x)
    LinkNode *newNode;

    if (Q.head->data == NUM) // 判满
        return false;
        
    newNode = (LinkNode *) malloc(sizeof(LinkNode));
    newNode->data = x;
    newNode->next = NULL;
    
    Q.head->data++; // 入队,增加一个元素
    Q.rear->next = newNode; // 队尾指针的指针域指向新结点
    Q.rear = newNode; // 队尾指针指向新结点
    return true;

以上是关于数据结构-队列队列的基本操作的主要内容,如果未能解决你的问题,请参考以下文章

莫队算法(离线)

数据结构 队列的简单理解和基本操作

数据结构之队列的基本操作以及栈和队列的OJ题画图详解

数据结构3. 栈和队列

队列的定义和两种存储结构下队列的基本操作

数据结构学习笔记——队列的基本知识和顺序存储结构实现队列(顺序队列)