-
概念
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
-
特点
队尾入队,队头出队,先进先出 -
队列的顺序存储实现
- 假溢出现象
当有队列元素进队的时候rear就会加一当打到MAXSIZE的时候就会被认为队列已满已近不能继续入队,但是此时出队一个元素front加一,这时候就会多出一个存储空间,但是应为rear已经等于MAXSIZE,所以无法再入队,这时就造成了假溢出现象,针对于这种现象一般会使用循环队列来解决类似问题。 - 循环队列
在实际使用队列时,为了使队列空间能重复使用,往往对队列的使用方法稍加改进:无论插入或删除,一旦rear指针增1或front指针增1 时超出了所分配的队列空间,就让它指向这片连续空间的起始位置。自己真从MaxSize-1增1变到0,可用取余运算rear%MaxSize和front%MaxSize来实现。这实际上是把队列空间想象成一个环形空间,环形空间中的存储单元循环使用,用这种方法管理的队列也就称为循环队列
- 初始化
#define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef int ElemType; typedef int Status; typedef struct { ElemType * data; int rear; int front; int maxSize; }Queue; //初始化 Status initQueue(Queue *q,int maxSize){ q->data = (ElemType *)malloc(sizeof(ElemType) * maxSize); if(q->data == NULL) exit(0); q->rear = 0; q->front = 0; q->maxSize = maxSize; return OK; }- 判空、判满、获取队列长度、获取队尾元素、遍历
//判空 Status queueIsEmpty(Queue q){ if(q.data == NULL) exit(0); if(q.rear == q.front) return TRUE; return FALSE; } //判断队列是否为满队列 Status queueIsFull(Queue q){ if(q.data == NULL) exit(0); if((q.rear + 1)%q.maxSize == q.front) return TRUE; return FALSE; } //获取队列长度 int getLength(Queue q){ if(q.data == NULL) exit(0); return (q.rear - q.front + q.maxSize)%q.maxSize; } //获取队尾元素 Status getRear(Queue q, ElemType *data){ if(q.data == NULL) exit(0); if(queueIsEmpty(q)) return ERROR; *data = q.data[q.rear-1]; return OK; } //遍历 Status traverseQueue(Queue q){ if(q.data == NULL) exit(0); for(int i = q.front; i != q.rear; i = (i+1)%q.maxSize) printf("%d ",q.data[i]); printf("\n"); return OK; }- 入队


//入队 Status enqueue(Queue *q,ElemType data){ if(q->data == NULL) exit(0); if(queueIsFull(*q)) return ERROR; q->data[q->rear] = data; q->rear = (q->rear + 1) % q->maxSize; return OK; }- 出队
//出队 Status dequeue(Queue *q){ if(q->data == NULL) exit(0); if(queueIsEmpty(*q)) return ERROR; q->front = (q->front + 1)%q->maxSize; return OK; } - 假溢出现象
-
队列的链式存储实现
- 初始化
#define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef int ElemType; typedef int Status; typedef struct QueueNode{ ElemType data; struct QueueNode * next; }QueueNode,*QueueNodePtr; typedef struct Queue{ QueueNodePtr front; QueueNodePtr rear; }Queue; //初始化 Status initQueue(Queue *q){ q->front = q->rear = (QueueNodePtr)malloc(sizeof(QueueNode)); if(q->front == NULL) exit(0); q->front->next = NULL; return OK; }- 判空、获取队尾元素、清空队列、销毁队列
//判空 Status queueIsEmpty(Queue q){ if(q.front == NULL) exit(0); if(q.front == q.rear) return TRUE; return FALSE; } //获取队尾元素 Status getRear(Queue q, ElemType *data){ if(q.front == NULL) exit(0); if(queueIsEmpty(q)) return ERROR; *data = q.rear->data; return OK; } //清空队列 Status clearQueue(Queue *q){ if(q->front == NULL) exit(0); if(queueIsEmpty(*q)) return ERROR; q->rear = q->front->next; while (q->rear !=NULL) { q->front->next = q->rear->next; free(q->rear); q->rear = q->rear->next; } q->rear = q->front; return OK; } //销毁队列 Status destroyQueue(Queue *q){ if(q->front == NULL) exit(0); if(clearQueue(q)){ q->front = q->rear =NULL; return OK; } return ERROR; }- 入队

//入队 Status enqueue(Queue *q,ElemType data){ if(q->front == NULL) exit(0); QueueNodePtr ptr = (QueueNodePtr)malloc(sizeof(QueueNode)); ptr->data = data; ptr->next = q->front->next; q->front->next = ptr; if(q->front == q->rear){ q->rear = ptr; } return OK; }- 出队

//出队 Status dequeue(Queue *q){ if(q->front == NULL) exit(0); if(queueIsEmpty(*q)) return ERROR; QueueNodePtr temp = q->rear; QueueNodePtr target = q->front; while (target->next != temp) { target = target->next; } target->next = NULL; q->rear = target; free(temp); return OK; }