a queue is a linear table that allows an insert operation at one end only, while a delete operation at the other end (insert operation at the end of the queue, delete on the head) .
In contrast to stacks, a queue is a Advanced First Out linear table (first in first out, FIFO).
The same as the stack, the queue is also an important linear structure, the implementation of a queue also requires a sequential table or linked list as the basis.
Chained storage structure for queues
Queues can be implemented either in a linked list or in a sequential table. Contrary to the stack, the stack is usually implemented by the sequential table, and the queue we use the list to implement, short for the chain queue.
typedef struct QNODE {elemtype data;struct qnode *next;} Qnode, *queueprt;</span>
<span style= "FONT-FAMILY:KAITI_GB2312;FONT-SIZE:18PX;" > typedef struct {queueprt front;//Team head QUEUEPRT rear;//team tail pointer} linkqueue;
The team head pointer points to the head node of the chain queue, and the tail pointer points to the endpoint node. (Note: The head node is not necessary, but for the convenience of operation, we added.) )
chained storage structure for queues
empty queues, both front and rear point to the head node.
Create a queue
Create a queue to accomplish 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 resulting header node, because this is an empty queue at that point.
Initqueue (Linkqueue *q) {q->front=q->rear= (queueptr) malloc (sizeof (Qnode)), if (!q->front) exit (0);q-> Front->next = NULL;}
into queue operations
into the queue operation Insertqueue (Linkqueue *q, Elemtype e) {queueptr p; p = (queueptr) malloc (sizeof (Qnode)), if (p = = NULL) exit (0); P-&G T;data = E;p->next = Null;q->rear->next = P;q->rear = P;}
Out-of-
queue operations
The out-of-queue operation is to move the first element in the queue out, team head pointer does not change , you can change the next pointer of the head node.
If the original queue has only one element, then we should deal with the tail pointers.
Out-of- queue operations
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);}
destroying a queue
Because the chain queue is built in the dynamic area of the memory, it should be destroyed in time when a queue is no longer useful, so as not to occupy too much memory space.
Destroyqueue (Linkqueue *q) {while (Q->front) {q->rear = Q->front->next;free (q->front); Q->front = q-& Gt;rear;}}
sequential storage structure of queues
We assume that a queue has n elements, the sequentially stored queue needs to establish a storage unit greater than n , and store all the elements of the queue in front of the array N units, the array is labeled 0 at one end is the team head.
The in-queue operation is actually to append an element at the end of the team, without any movement, and with a time complexity of O (1).
Out of the queue is different, because we have set the location labeled 0 is the queue's head, so each out of the queue operation of all elements to move forward.
In reality, too, a group of people in line to buy train tickets, the front of the people bought to leave, behind the people will all forward a step to fill the vacancy.
but we one of the fundamental aims of studying data structures and algorithms is to find ways to improve the efficiency of our programs . , the time complexity of the queue is O (n), and the efficiency is greatly reduced, according to the way just now!
If we do not limit the team head must be placed in the next 0 position, then the operation out of the queue does not need to move the whole element.
However, there are some problems, such as the continuation of the queue in the same situation as below, there will be an array out of bounds error.
But in fact we have 0 and 1 two subscript still empty, this is called false overflow.
Loop Queue ( very wide application in practice )
We think again, the solution to the false overflow is if the back full, and then start from the beginning, that is, the end-to-end cycle.
Loop queue Its capacity is fixed, and its team head and tail pointers can all be entered with the element , out of the queue, so that the loop queue logically appears to be a circular storage space.
It is important to note, however, that in actual memory there is no real ring storage, we are simply simulating the logical loops with sequential tables.
So we realized that it seems that the implementation of the loop queue only has to change the front and rear pointers flexibly.
That is, let the front or rear pointer continue to add 1, i.e. make the address range is exceeded and will automatically start from the beginning. We can take modulo operations :( This operation is particularly common in data structures and is particularly important!) )
(rear+1)% queuesize
(front+1)% queuesize
modulo is the meaning of the remainder, and the value he takes will never be greater than the divisor .
define a loop queue
#define MAXSIZE 100typedef Struct{elemtype *base;//For storing the memory allocation base address, here you can also use an array to store int front;int rear; Initializes a circular queue initqueue (Cyclequeue *q) {q->base = (Elemtype *) malloc (MAXSIZE * sizeof (elemtype)); if (!q->base) Exit (0); Q->front = Q->rear = 0;} into the queue operation Insertqueue (Cyclequeue *q, Elemtype e) {if ((q->rear+1)%maxsize = = Q->front) return;//Queue full q->base[q-> Rear] = E;q->rear = (q->rear+1)% MAXSIZE;} Out queue Operation Deletequeue (Cyclequeue *q, Elemtype *e) {if (Q->front = = q->rear) return;//queue is empty *e = q->base[q->front]; Q->front = (q->front+1)% MAXSIZE;}
Sequential storage structure and chained storage structure for queues