队列结构
队列(Queue)是从数据的运算来分类的,按照 先进先出(First In First Out,FIFO)
的原则处理结点数据的。而从数据的逻辑结构来看,队列结构其实就是一种线性结构。
队列结构包括两类
- 顺序队列结构:使用一组地址连续的内存单元依次保存队列中的数据。
- 链式队列结构:使用链表形式保存队列中的数据。
(顺序)队列操作实例代码
数据准备
定义(顺序)队列结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #define MAX_LEN 100
typedef enum { RetError = -1, RetFailure = 0, RetSuccess = 1, }RetValue;
typedef struct { char key[15]; char name[20]; int age; }NodeData;
typedef struct { NodeData QueueData[MAX_LEN]; int head; int tail; }SQType;
|
(顺序)队列相关操作
(顺序)队列初始化
1 2 3 4 5 6 7 8 9 10 11 12
| SQType* SQueueInit() { SQType* pQueue; if (!(pQueue = (SQType*)malloc(sizeof(SQType)))) { printf("无法分配队列内存,(顺序)队列初始化失败!\n"); return NULL; } pQueue->head = 0; pQueue->tail = 0; return pQueue; }
|
(顺序)空队列判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| RetValue SQueueIsEmpty(SQType* pQueue) { if (NULL == pQueue) { printf("(顺序)队列指针不存在,无法进行空队列判断!\n"); return RetError; } if (pQueue->tail == pQueue->head) { return RetSuccess; } else { return RetFailure; } }
|
(顺序)满队列判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| RetValue SQueueIsFull(SQType* pQueue) { if (NULL == pQueue) { printf("(顺序)队列指针不存在,无法进行满队列判断!\n"); return RetError; } if (MAX_LEN == pQueue->tail) { return RetSuccess; } else { return RetFailure; } }
|
(顺序)队列清空
1 2 3 4 5 6 7 8 9 10 11 12
| RetValue SQueueClear(SQType* pQueue) { if (NULL == pQueue) { printf("(顺序)队列指针不存在,无法进行队列清空!\n"); return RetError; } pQueue->head = 0; pQueue->tail = 0; return RetSuccess; }
|
(顺序)队列释放
1 2 3 4 5 6 7 8 9 10 11
| RetValue SQueueFree(SQType* pQueue) { if (NULL == pQueue) { printf("(顺序)队列指针不存在,无法进行队列释放!\n"); return RetError; } free(pQueue); return RetSuccess; }
|
入(顺序)队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| RetValue SQueueIn(SQType* pQueue, NodeData inData) { if (NULL == pQueue) { printf("(顺序)队列指针不存在,无法入队列!\n"); return RetError; } if (RetSuccess == SQueueIsFull(pQueue)) { printf("(顺序)队列已满,无法入队列!\n"); return RetFailure; } pQueue->QueueData[pQueue->tail] = inData; pQueue->tail++; return RetSuccess; }
|
出(顺序)队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| RetValue SQueueOut(SQType* pQueue, NodeData* outData) { if (NULL == pQueue) { printf("(顺序)队列指针不存在,无法出队列!\n"); return RetError; } if (RetSuccess == SQueueIsEmpty(pQueue)) { printf("(顺序)队列为空,无法出队列!\n"); return RetFailure; } *outData = pQueue->QueueData[pQueue->head]; pQueue->head++; return RetSuccess; }
|
读取(顺序)队头结点数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| RetValue SQueuePeek(SQType* pQueue, NodeData* peekData) { if (NULL == pQueue) { printf("(顺序)队列指针不存在,无法读取队列顶数据!\n"); return RetError; } if (RetSuccess == SQueueIsEmpty(pQueue)) { printf("(顺序)队列为空,队列顶数据不存在!\n"); return RetFailure; } *peekData = pQueue->QueueData[pQueue->head]; return RetSuccess; }
|
计算(顺序)队列长度
1 2 3 4 5 6 7 8 9 10 11
| unsigned int SQueueLength(SQType* pQueue) { if (NULL == pQueue) { printf("(顺序)队列指针不存在,无法计算队列长度!\n"); return 0; } unsigned int qLen = pQueue->tail - pQueue->head;
return qLen; }
|
显示(顺序)队列所有数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| RetValue SQueueShowAll(SQType* pQueue) { if (NULL == pQueue) { printf("(顺序)队列指针不存在,无法显示队列所有数据!\n"); return RetError; } if (RetSuccess == SQueueIsEmpty(pQueue)) { printf("(顺序)队列为空,队列数据不存在!\n"); return RetFailure; } for (int i = pQueue->head; i < pQueue->tail; i++) { printf("key = %-15s name = %-20s age = %d\n", pQueue->QueueData[i].key, pQueue->QueueData[i].name, pQueue->QueueData[i].age); } return RetSuccess; }
|
(链式)队列操作实例代码
数据准备
定义(链式)队列结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| typedef enum { RetError = -1, RetFailure = 0, RetSuccess = 1, }RetValue;
typedef struct { char key[15]; char name[20]; int age; }NodeData;
typedef struct node { NodeData nodeData; struct node* nextNode; }LQType;
|
定义“头”结构
1 2 3 4 5 6
| typedef struct _head { LQType* headNode; LQType* tailNode; unsigned int lqLength; }Head;
|
(链式)队列相关操作
(链式)队列初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Head* LQueueInit() { Head* pHead; if (!(pHead = (Head*)malloc(sizeof(Head)))) { printf("无法分配队列头指针内存,(链式)队列初始化失败!\n"); return NULL; } pHead->headNode = NULL; pHead->tailNode = NULL; pHead->lqLength = 0; return pHead; }
|
空(链式)队列判断
1 2 3 4 5 6 7 8 9 10 11 12 13
| RetValue LQueueIsEmpty(Head* pHead) { if (NULL == pHead) { printf("(链式)队列指针不存在,无法进行为空判断!\n"); return RetError; } if (0 == pHead->lqLength) { return RetSuccess; } return RetFailure; }
|
入(链式)队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| RetValue LQueueIn(Head* pHead, NodeData inData) { if (NULL == pHead) { printf("(链式)队列指针不存在,无法入队列\n"); return RetError; } LQType* newNode; if (!(newNode = (LQType*) malloc(sizeof(LQType)))) { printf("新添加结点内存申请失败,无法入队列!\n"); return RetFailure; } newNode->nodeData = inData; newNode->nextNode = NULL; if (NULL == pHead->tailNode) { pHead->headNode = newNode; } else { pHead->tailNode->nextNode = newNode; } pHead->tailNode = newNode; pHead->lqLength++; return RetSuccess; }
|
出(链式)队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| RetValue LQueueOut(Head* pHead, NodeData* outData) { if (NULL == pHead) { printf("(链式)队列指针不存在,无法入队列\n"); return RetError; } if (RetSuccess == LQueueIsEmpty(pHead)) { printf("队列内无结点,无法出队列!\n"); return RetFailure; } memcpy(outData, &pHead->headNode->nodeData, sizeof(NodeData)); LQType* deleteNode = pHead->headNode; pHead->headNode = pHead->headNode->nextNode; pHead->lqLength--; free(deleteNode); return RetSuccess; }
|
销毁(链式)队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| RetValue LQueueDestroy(Head* pHead) { if (NULL == pHead) { printf("(链式)队列指针不存在,无法销毁队列\n"); return RetError; } LQType* deleteNode; while (pHead->headNode) { deleteNode = pHead->headNode; pHead->headNode = pHead->headNode->nextNode; free(deleteNode); } pHead->tailNode = NULL; pHead->headNode = NULL; free(pHead); return RetSuccess; }
|
读取(链式)队头数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| RetValue LQueuePeek(Head* pHead, NodeData* peekData) { if (NULL == pHead) { printf("(链式)队列指针不存在,无法读取队列顶数据!\n"); return RetError; } if (RetSuccess == LQueueIsEmpty(pHead)) { printf("(链式)队列为空,队列顶数据不存在!\n"); return RetFailure; } *peekData = pHead->headNode->nodeData; return RetSuccess; }
|
显示(链式)队列所有结点数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| RetValue LQueueShowAll(Head* pHead) { if (NULL == pHead) { printf("(链式)队列指针不存在,无法显示队列所有数据!\n"); return RetError; } if (RetSuccess == LQueueIsEmpty(pHead)) { printf("(链式)队列为空,队列数据不存在!\n"); return RetFailure; } LQType* tempHead = pHead->headNode; while (tempHead) { printf("key = %-15s name = %-20s age = %d\n", tempHead->nodeData.key, tempHead->nodeData.name, tempHead->nodeData.age); tempHead = tempHead->nextNode; } return RetSuccess; }
|