队列的基本概念 :
队列和栈一样是一种特殊的线性表。
栈是一种后进先出的数据结构。比如入栈顺序为1,2,3,4,5的时候,出栈顺序可能为5, 4, 3, 2, 1。可能为1,24,3,5
队列和平时的排队打饭一样,先进入队列的先出去,是按照进入的顺序来出队列的,比如入队列顺序为1,2,3,4,5的时候,出队列顺序只可能为1,2,3,4,5
进行插入操作的端称为队尾,进行删除操作的端称为队头。当队列中没有元素的时候,称为空队列。
队列存储结构
顺序队列
使用数组:
队头指针不动----要大量搬移元素
队头是arr[0] 所以每次出队列都会把arr[0] 之后的元素向前搬移。所以太耗费时间。
队头指针移动----存在假溢出
循环队列如何解决队列空或者满?
少存储一个元素,在判断的时候,判断(tail + 1) % size 看是否等于head,如果相等代表队列满了,队列为空的时候,tail == head。
链式队列---用链表作为队列的底层数据结构 :
操作:
- 队列初始化
- 入队列
- 出队列
- 队列判空
- 获取队首元素
- 获取队尾元素
- 获取队列中元素个数
代码如下:
#include <stdio.h> #include <stdlib.h> typedef int DataType; /** *队列中的节点 */ typedef struct Node { DataType _data; struct Node* _pNext; }*PNode, Node; /** *队列 pHead 队头指针 pTail 队尾指针 size 队列大小 */ typedef struct Queue { struct Node* pHead; struct Node* pTail; }Queue; /** 初始化队列 */ void QueueInit(Queue* queue); /** 入队 */ void QueuePush(Queue* queue, DataType data); /** 出队列 */ int QueuePop(Queue* queue, DataType* data); /** 判空 */ int QueueEmpty(Queue* queue); /** 取队头元素 */ DataType QueueFront(Queue* q); /** 取队尾元素 */ DataType QueueBack(Queue* q); /** 获取队列中元素的个数 */ int QueueSize(Queue* q); void TestQueue(); int main() { TestQueue(); return 0; } void TestQueue() { Queue* queue = (Queue*)malloc(sizeof(Queue)); QueueInit(queue); QueuePush(queue, 4); QueuePush(queue, 5); QueuePush(queue, 6); printf("队列中元素个数为%d\n\n", QueueSize(queue)); printf("队列是否为空:%s\n", QueueEmpty(queue) == 1 ? "为空" : "不为空"); printf("队头为%d\n", QueueFront(queue)); printf("队尾为%d\n", QueueBack(queue)); int a; QueuePop(queue, &a); printf("\n出队列%d\n", a); QueuePop(queue, &a); printf("出队列%d\n", a); QueuePop(queue, &a); printf("出队列%d\n", a); printf("队列中元素个数为%d\n\n", QueueSize(queue)); printf("队列是否为空:%s\n\n", QueueEmpty(queue) == 1 ? "为空" : "不为空"); } void QueueInit(Queue* queue) { if (queue == NULL) return; queue->pHead = NULL; queue->pTail = NULL; } void QueuePush(Queue* queue, DataType data) { if (queue == NULL) return; PNode node = (PNode)malloc(sizeof(Node)); if (node == NULL) return; node->_pNext = NULL; node->_data = data; if (queue->pHead == NULL) { queue->pHead = node; queue->pTail = node; } else { queue->pTail->_pNext = node; queue->pTail = node; } } int QueuePop(Queue* queue, DataType* data) { if (queue == NULL) return 0; if (queue->pHead == NULL) return 0; *data = queue->pHead->_data; PNode pre = queue->pHead; queue->pHead = queue->pHead->_pNext; pre->_pNext = NULL; free(pre); return 1; } int QueueEmpty(Queue* queue) { if (queue->pHead == NULL) return 1; return 0; } // 取队头元素 DataType QueueFront(Queue* q) { if (q == NULL || q->pHead == NULL) return -1; return q->pHead->_data; } // 取队尾元素 DataType QueueBack(Queue* q) { if (q == NULL || q->pTail == NULL) return -1; return q->pTail->_data; } // 获取队列中元素的个数 int QueueSize(Queue* q) { if (q == NULL || q->pHead == NULL) return 0; PNode cur = q->pHead; int count = 1; while (cur != q->pTail) { cur = cur->_pNext; count++; } return count; }
运行结果: