The queue is like a queue in life and has the following properties:
1) each time you add an element, you must add it at the end of the team.
2) each time an element is taken away, it must be taken from the opposite side.
To sum up, it means first-in-first-out, and then-out.
From the storage point of view, there are two ways to implement Queues: one is continuous storage and the other is discrete storage. Continuous storage is similar to arrays, while discrete storage is similar to a linked list. Here we first implement simple continuous storage:
Because the queue operation can be performed either at the right or at the end of the team, that is, it can be operated at both ends, so we need to use two parameters to describe: head and tail. One points to the opposite and the other points to the next one at the end of the team.
Here, it is explained that when the queue is empty, head = tial, and when the queue is full, head = tail, which leads to ambiguity. To avoid ambiguity, we define that tail points to the next element at the end of the team, so that when the queue
If it is empty, head = tail, and when the queue is full, tail + 1 = head. That is to say, if we have N spaces, we can only use N-1, to leave one for tail. When head and tail move, we are not
Simply add 1 to them, but add 1 to them and then modulo N. In this way, we can cyclically get from 0 ~ The number of N-1.
For specific implementation, see the source code:
/*************************************************************************> File Name: sequeue.c> Author: Baniel Gao> Mail: createchance@163.com > Blog: blog.csdn.net/createchance > Created Time: Fri 20 Dec 2013 11:57:32 AM CST ************************************************************************/#include
#include
#define _DEBUG_ 1typedef struct _sequeue_ {int total;int head;int tail;int *data;} sequeue_st;sequeue_st *sequeue_init(int size);int sequeue_enqueue(sequeue_st *queue, int value);int sequeue_isfull(sequeue_st *queue);int sequeue_dequeue(sequeue_st *queue);int sequeue_isempty(sequeue_st *queue);int sequeue_free(sequeue_st *queue);#if _DEBUG_int sequeue_debug(sequeue_st *queue);#endifint main(void){sequeue_st *queue;int size = 10;int value = 100;queue = sequeue_init(size);while (-1 != sequeue_enqueue(queue, value))value++;#if _DEBUG_printf("After enqueue......\n");sequeue_debug(queue);#endifwhile (-1 != sequeue_dequeue(queue))value++;#if _DEBUG_printf("After dequeue......\n");sequeue_debug(queue);#endifsequeue_free(queue);return 0;}sequeue_st *sequeue_init(int size){sequeue_st *queue = NULL;queue = (sequeue_st *)malloc(sizeof(sequeue_st));queue->head = 0;queue->tail = 0;queue->total = size;queue->data = (int *)malloc(sizeof(int) * size);return queue;}int sequeue_enqueue(sequeue_st *queue, int value){if (sequeue_isfull(queue))return -1;queue->data[queue->tail] = value;queue->tail = (queue->tail + 1) % queue->total;return 0;}int sequeue_dequeue(sequeue_st *queue){if (sequeue_isempty(queue))return -1;queue->head = (queue->head + 1) % queue->total;return 0;}int sequeue_isempty(sequeue_st *queue){if (queue->tail == queue->head)return 1;return 0;}int sequeue_isfull(sequeue_st *queue){if ((queue->tail + 1) % queue->total == queue->head)return 1;return 0;}int sequeue_free(sequeue_st *queue){free(queue->data);free(queue);return 0;}int sequeue_debug(sequeue_st *queue){int index;puts("------------------------ DEBUG ----------------------");printf("total = %d\thead = %d\ttail = %d\n", queue->total, queue->head, queue->tail);puts("-----------------------------------------------------");for (index = 0; index < queue->total; index++)printf("%5d", queue->data[index]);puts("\n-----------------------------------------------------");return 0;}
Here, I have defined a debug function for controlling and viewing the queue, and can block it With Conditional compilation.
Running result:
In this way, you can clearly see the operations for joining and leaving the team.