(8) Queue

A first-in, first-out linear table that performs insertion operations at one end and delete operations at the other end is a first-in, first-out linear table.

1. Chained storage of queues

(1) Chain storage structure of queue

typedef struct QNode 
{
  ElemType data;		
  struct QNode *next;
} QNode, *QueuePrt;
typedef struct 
{
  QueuePrt front, rear; // 队头、尾指针
} LinkQueue;

Point the head of the queue to the head node of the chain queue, and the tail of the queue to the terminal node (Note: The head node is not necessary, but for convenience of operation, add

 When the queue is empty, both front and rear point to the head node

 (2)  Create a queue

Creating a queue requires two tasks: one is to create a head node in memory, and the other is to point both the head and tail pointers of the queue to the generated head node, because it is an empty queue at this time.

initQueue(LinkQueue *q)
{
   q->front=q->rear=(QueuePtr)malloc(sizeof(QNode));
   if( !q->front ) exit(0);
   q->front->next = NULL;
}

(3)  into the queue

InsertQueue(LinkQueue *q, ElemType e)
{
    QueuePtr p;
    p = (QueuePtr)malloc(sizeof(QNode));
    if( p == NULL ) exit(0);
    p->data = e;
    p->next = NULL;
    q->rear->next = p;
    q->rear = p;
}

(4) Dequeue

Remove the first element in the queue, the head pointer does not change, just change the next pointer of the head node. If the original queue has only one element, the tail pointer is processed.

DeleteQueue(LinkQueue *q, ELemType *e)
{
   QueuePtr p;
   if( q->front == q->rear ) return;
   p = q->front->next;
   *e = p->data;
   q->front->next = p->next;
   if( q->rear == p ) q->rear = q->front;
   free(p);
}

(5)  Destroy the queue

Since the chain queue is established in the dynamic area of ​​the memory, when a queue is no longer useful, it should be destroyed in time to avoid taking up too much memory space.

DestroyQueue(LinkQueue *q)
{
   while( q->front ) {
     q->rear = q->front->next;
     free( q->front );
     q->front = q->rear;
 }
}

2. Sequential storage of queues

Assuming that a queue has n elements, the queue for sequential storage needs to create a storage unit larger than n, and store all the elements of the queue in the first n units of the array, and the end of the array subscript 0 is the head of the queue. The enqueue operation is to append an element to the end of the queue without any movement, and the time complexity is O(1). Dequeue is different, because it has been assumed that the position with index 0 is the head of the queue, so all elements must be moved forward for each dequeue operation.

 3. Circular queue

The capacity is fixed, and its head and tail pointers can change as elements enter and leave the queue, thus creating a circular storage space.

(1)  Let the front or rear pointer continue to increase by 1, and use the modulo operation to process

(rear+1) % QueueSize   (front+1) % QueueSize

(2)  Define a circular queue

#define MAXSIZE 100
typedef struct
{
   ElemType *base; // 用于存放内存分配基地址,这里你也可以用数组存放
   int front;
   int rear;
}

(3)  Initialize the circular queue

initQueue(cycleQueue *q)
{
       q->base = (ElemType *) malloc (MAXSIZE * sizeof(ElemType));
       if( !q->base )  exit(0);
       q->front = q->rear = 0;
}

(4)  Enter the queue

InsertQueue(cycleQueue *q, ElemType e)
{
    if( (q->rear+1)%MAXSIZE == q->front ) return; // 队列已满
     q->base[q->rear] = e;
     q->rear = (q->rear+1) % MAXSIZE;
}

(5)  out of the queue

DeleteQueue(cycleQueue *q, ElemType *e)
{
   if( q->front == q->rear )  return;
   *e = q->base[q->front];
   q->front = (q->front+1) % MAXSIZE;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324049504&siteId=291194637