Data structure - stack and queue

Posted by mdnghtblue on Fri, 17 Sep 2021 21:50:53 +0200

Link, data structure - stack and queue (2) stack
Data structure - stack and queue (II) stack

data structure

Stack and queue (II) queue

Mind map




3.2.1 basic concept of queue

1. Concept

A Queue is a linear table that can only be inserted at one end and deleted at the other end

Queue is a special linear structure. It only allows deletion at the head/front of the queue, which is called "out of the queue", and insertion at the tail/rear of the queue, which is called "in the queue". When there are no elements in the queue (i.e. head == tail), it is called an empty queue. For example, to buy a ticket, each window in line to buy a ticket is a queue. In this queue, newcomers always stand at the back of the queue. The earlier they come, the more front they are, that is, the sooner they can buy tickets. We call it the "first in first out (FIFO) principle. 🚘

  • Queue is a sequential list, which can be implemented by array or linked list
  • Delete elements at the head of the queue and insert elements at the end of the queue
  • First in first out (FIFO) principle

2. Basic operation

Queue basic operations

Initqueue: initialize the queue and construct an empty queue.

Destroy & queue: destroy the queue. Destroy and free the memory space occupied by queue Q.

Enqueue (& Q, x): join the queue. If queue q is not full, add x to make it a new tail.

Dequeue (& Q, & x): out of the queue. If queue q is not empty, delete the queue header element and return it with X.

Gethead (Q, & x): read the queue header element. If queue q is not empty, assign the queue header element to X.

Other common operations:

QueueEmpty(Q): judge that the queue is empty. If the queue Q is empty, return true; otherwise, return false.

3.2.2 sequential queue

1. Sequential queue

Initial state (empty state): Q.front == Q.rear == 0

Queue entry operation: if the queue is not satisfied, first send the value to the queue end element, and then add 1 to the queue end pointer

Out of queue operation: if the queue is not empty, first go to the element value of the queue head, and then add 1 to the queue head pointer

An "upper overflow", i.e. "false overflow", will appear

2. Circular queue

In order to solve the "false overflow" of sequential queue and make full use of space, that is, the table storing queue elements is logically regarded as a ring.

The storage space is logically changed into a "ring" by modular operation. Modulo operation, i.e. remainder operation. Two integers a,b, a% b = = the remainder of a divided by b.

Empty status: Q.front == Q.rear;

Queue full status: (q.rear + 1)% maxsize = = q.front

Incoming operation: (q.rear + 1)% maxsize

Outgoing operation: (q.front + 1)% maxsize

Number of queues: (q.rear - q.front + maxsize)% maxsize


3. How to distinguish between empty and full teams

(1)

Sacrifice a storage unit and the queue is full: the next position of the queue tail pointer is the queue head,

That is, (Q.rear+1)%MaxSize == Q.front

(2)

Add a data member representing the number of elements in the type.

Successfully inserted size + +;

Successfully deleted size –;

Queue full condition: size==MaxSize

Queue empty condition: size == 0;

Number of queue elements = size

(3)

Add tag data member in type

Make tag=0 every time the deletion operation is successful;

When each insertion operation is successful, make tag=1;

Full queue condition: front = = rear & & tag = = 1

Queue empty condition: front = = rear & & tag = = 0

4. Code implementation

#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#define MaxSize 10
using namespace std;

typedef struct {
    int data[MaxSize];
    int front, rear; //Queue head pointer and queue tail pointer
} SqQueue;

/**
 * @description: Initialize queue
 * @param {SqQueue} Q
 * @return {*}
 */
bool InitQueue(SqQueue &Q) {
    Q.front = Q.rear = 0; //Initialize queue
}

/**
 * @description: Judge team empty
 * @param {SqQueue} Q
 * @return {*}
 */
bool isEmpty(SqQueue Q) {
    return Q.front == Q.rear;
}

/**
 * @description: Determine whether there is overflow
 * @param {SqQueue} Q
 * @return {*}
 */
bool isFull(SqQueue Q) {
    //Sacrifice a unit to distinguish between empty and full teams
    return (Q.rear + 1) % MaxSize == Q.front;
}

/**
 * @description: Join the team
 * @param {SqQueue} &Q
 * @param {int} e
 * @return {*}
 */
bool EnQueue(SqQueue &Q, int e) {
    if(isFull(Q))
        return false;
    Q.data[Q.rear] = e; //Join the team
    Q.rear = (Q.rear + 1) % MaxSize; //The tail pointer moves back after taking the mold
    return true;    
}

/**
 * @description: Out of the team
 * @param {SqQueue} &Q
 * @param {int} &e
 * @return {*}
 */
bool DeQueue(SqQueue &Q, int &e) {
    if(isEmpty(Q))
        return false;
    e = Q.data[Q.front];    
    Q.front = (Q.front + 1) % MaxSize; //The team head pointer moves back after taking the mold
    return true;
}

/**
 * @description: Get header element
 * @param {SqQueue} Q
 * @return {*}
 */
int
    GetTop(SqQueue Q)
{
    if(isEmpty(Q))
        return -1;
    return Q.data[Q.front];
}

/**
 * @description: Get queue length
 * @param {SqQueue} Q
 * @return {*}
 */
int GetLength(SqQueue Q) {
    if(isEmpty(Q))
        return -1;
    return (Q.rear - Q.front + MaxSize) % MaxSize;
}

/**
 * @description: Show queue
 * @param {SqQueue} Q
 * @return {*}
 */
void printQueue(SqQueue Q)
{
    int t = Q.front;
    int len = t + GetLength(Q);

    for (int i = t; i < len; i++)
    {
        cout << "queue[" << i % MaxSize << "] = " << Q.data[i % MaxSize] << endl;
    }
}
int main() {
    SqQueue Q;
    InitQueue(Q);
    bool loop = true;
    while (loop)
    {
        system("pause");
        system("cls");
        cout << "Welcome to the queue operation. Please operate according to the specified serial number. The postgraduate entrance examination is successful!" << endl;
        cout << "---------------------menu---------------------" << endl;
        cout << "1,Join the team" << endl;
        cout << "2,Out of the team" << endl;
        cout << "3,Output team" << endl;
        cout << "4,View team header elements" << endl;
        cout << "5,View team leader" << endl;
        cout << "0,sign out" << endl;
        int num;
        cout << "Please select serial number:";
        cin >> num;
        switch (num)
        {
        case 1:
            if (isFull(Q))
            {
                cout << "Team full" << endl;
            }
            else
            {
                int e;
                cout << "Please enter data:";
                cin >> e;
                EnQueue(Q, e);
            }

            break;
        case 2:
            if (isEmpty(Q))
            {
                cout << "Team air" << endl;
            }
            else
            {
                int e = -1;
                DeQueue(Q, e);
                cout << "Outgoing data are:" << e << endl;
            }
            break;
        case 3:
            if (isEmpty(Q))
                cout << "Team air" << endl;
            else
                printQueue(Q);
            break;
        case 4:
            if (isEmpty(Q))
            {
                cout << "Team air" << endl;
            }
            else
            {
                cout << "The data at the top of the team are: " << GetTop(Q) << endl;
            }
            break;
        case 5:
            cout << "The team leader is:" << GetLength(Q) << endl;
            break;
        case 0:
            loop = false;
            break;
        case 6:

            break;
        default:
            break;
        }
    }
    return 0;
}

5. Effect realization



3.2.3 chain queue

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#define MaxSize 10
using namespace std;

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

typedef struct {   //Link queue
    int size;
    LinkNode *front, *rear; //Queue head pointer and queue tail pointer
}LinkQueue;

/**
 * @description: Initialize queue
 * @param {LinkQueue} Q
 * @return {*}
 */
bool InitQueue(LinkQueue &Q)
{
    Q.front = Q.rear = (LinkNode *)malloc(sizeof(LinkNode)); //Create header node
    Q.front->next = NULL;
    Q.size = 0;
    return true;
}

/**
 * @description: Judge team empty
 * @param {LinkQueue} Q
 * @return {*}
 */
bool isEmpty(LinkQueue Q)
{
    // return Q.front == Q.rear;
    return Q.size == 0;
}

/**
 * @description: Join the team
 * @param {LinkQueue} &Q
 * @param {int} e
 * @return {*}
 */
bool EnQueue(LinkQueue &Q, int e)
{
    LinkNode *t;
    t = (LinkNode *)malloc(sizeof(LinkNode));
    t->data = e;
    t->next = NULL;
    Q.rear->next = t; //Join the team
    Q.rear = t;  //End of line pointer backward
    Q.size++;
    return true;
}

/**
 * @description: Out of the team
 * @param {LinkQueue} &Q
 * @param {int} &e
 * @return {*}
 */
bool DeQueue(LinkQueue &Q, int &e)
{
    if (isEmpty(Q))
        return false;
    LinkNode *p = Q.front->next;    
    e = p->data;
    Q.front->next = p->next;  //The queue head pointer moves back
    if(Q.rear == p) 
        Q.rear = Q.front;  //If the original queue has only one node, it will become empty after deletion
    free(p);    
    Q.size--;
    return true;
}

/**
 * @description: Get header element
 * @param {LinkQueue} Q
 * @return {*}
 */
int GetTop(LinkQueue Q)
{
    if (isEmpty(Q))
        return -1;
    return Q.front->next->data;
}

/**
 * @description: Get queue length
 * @param {LinkQueue} Q
 * @return {*}
 */
int GetLength(LinkQueue Q)
{
    return Q.size;
}

/**
 * @description: Show queue
 * @param {LinkQueue} Q
 * @return {*}
 */
void printQueue(LinkQueue Q)
{
    LinkNode *t = Q.front->next;
    while (t != NULL)
    {
        cout << t->data << "->";
        t = t->next;
    }
    printf("\n");
}
int main()
{
    LinkQueue Q;
    InitQueue(Q);
    bool loop = true;
    while (loop)
    {
        system("pause");
        system("cls");
        cout << "Welcome to the queue operation. Please operate according to the specified serial number. The postgraduate entrance examination is successful!" << endl;
        cout << "---------------------menu---------------------" << endl;
        cout << "1,Join the team" << endl;
        cout << "2,Out of the team" << endl;
        cout << "3,Output team" << endl;
        cout << "4,View team header elements" << endl;
        cout << "5,View team leader" << endl;
        cout << "0,sign out" << endl;
        int num;
        cout << "Please select serial number:";
        cin >> num;
        switch (num)
        {
        case 1:
            int e;
            cout << "Please enter data:";
            cin >> e;
            EnQueue(Q, e);
            break;
        case 2:
            if (isEmpty(Q))
            {
                cout << "Team air" << endl;
            }
            else
            {
                int e = -1;
                DeQueue(Q, e);
                cout << "Outgoing data are:" << e << endl;
            }
            break;
        case 3:
            if (isEmpty(Q))
                cout << "Team air" << endl;
            else
                printQueue(Q);
            break;
        case 4:
            if (isEmpty(Q))
            {
                cout << "Team air" << endl;
            }
            else
            {
                cout << "The data at the top of the team are: " << GetTop(Q) << endl;
            }
            break;
        case 5:
            cout << "The team leader is:" << GetLength(Q) << endl;
            break;
        case 0:
            loop = false;
            break;
        case 6:

            break;
        default:
            break;
        }
    }
    return 0;
}

3.2.4 double ended queue

Topics: C C++ data structure queue