学习目标:学会熟悉操作队列
学习指导:帆神的代码
学习任务:
代码说明:
队列链表
- 运行过程中,哪些变量分配在相邻的空间?全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
- 局部变量的空间能否重复利用?举例说明。可以,循环链表就是。
- 指针的地址和值的区别是什么?传递指针指针所指的不容不会被改变,而传递地址则该地址的内容会被改变
- 队列的提出, 也是想获得 O(1) 的时间复杂。
循环队列
- 整除的作用.(循环的必要操作)
- 想像操场跑道里放一队人, 循环的感觉就出来了.
- 为了区分空队列与满队列, 需要留一个空间. 相当于不允许首尾相连. 还是画个图吧, 否则容易进坑.
- 用链式结构, 空间的分配与回收由系统做, 用循环队列, 则是自己把控. 想像自己写的是操作系统, 从这个代码可以感受下内存的管理.
学习时间:
2022.5.6
1链式队列
1.1全部代码
#include <stdio.h>
#include <malloc.h>
/**
* 链队列的节点.
*/
typedef struct LinkNode {
int data;
struct LinkNode* next;
}*LinkNodePtr, LinkNode;
/**
* 链队列.
*/
typedef struct LinkQueue {
LinkNodePtr front;
LinkNodePtr rear;
}*LinkQueuePtr, LinkQueue;
/**
* @brief 初始化队列
*
* @return 队列头节点
*/
LinkQueuePtr initQueue() {
//申请队列
LinkQueuePtr resultPtr = (LinkQueuePtr)malloc(sizeof(LinkQueue));
//申请头节点
LinkNodePtr headerPtr = (LinkNodePtr)malloc(sizeof(LinkNodePtr));
headerPtr->next = NULL;
resultPtr->front = headerPtr;
resultPtr->rear = headerPtr;
return resultPtr;
}
/**
* @brief 输出队列
*
* @param paraQueuePtr
*/
void outputLinkQueue(LinkQueuePtr paraQueuePtr) {
LinkNodePtr tempPtr = paraQueuePtr->front->next;
while (tempPtr != NULL) {
printf("%d ", tempPtr->data);
tempPtr = tempPtr->next;
}
printf("\n");
}
/**
* @brief 入队
*
* @param paraElement
* @param paraQueuePtr
*/
void enqueue(LinkQueuePtr paraQueuePtr, int paraElement) {
//1申请新的节点
LinkNodePtr tempNodePtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
tempNodePtr->data = paraElement;
tempNodePtr->next = NULL;
//2加入队列
paraQueuePtr->rear->next = tempNodePtr;
//3重置队尾
paraQueuePtr->rear = tempNodePtr;
printf("%d 入队\n",paraElement);
}
/**
* @brief 出队
*
* @param paraQueuePtr
*
* @return 出队的数据值
*/
int dequeue(LinkQueuePtr paraQueuePtr) {
int resultValue;
LinkNodePtr tempNodePtr;
//1判断队列是否为空
if (paraQueuePtr->front == paraQueuePtr->rear) {
printf("出队失败,队列为空.\n");
return -1;
}
//2改变队列
tempNodePtr = paraQueuePtr->front->next;
resultValue = tempNodePtr->data;
paraQueuePtr->front->next = paraQueuePtr->front->next->next;
if (paraQueuePtr->rear == tempNodePtr) {
paraQueuePtr->rear = paraQueuePtr->front;
}
//3释放出队的节点资源
free(tempNodePtr);
tempNodePtr = NULL;
//4返回出队值
return resultValue;
}
/**
* @brief 单元测试
*/
void testLinkQueue() {
printf("---- testLinkQueue 测试开始 ----\n");
LinkQueuePtr tempQueuePtr;
tempQueuePtr = initQueue();
enqueue(tempQueuePtr, 10);
enqueue(tempQueuePtr, 30);
enqueue(tempQueuePtr, 50);
printf("入队后队列为:\n");
outputLinkQueue(tempQueuePtr);
printf("出队 得到 %d\n", dequeue(tempQueuePtr));
printf("出队 得到 %d\n", dequeue(tempQueuePtr));
printf("出队 得到 %d\n", dequeue(tempQueuePtr));
printf("出队 得到 %d\n", dequeue(tempQueuePtr));
enqueue(tempQueuePtr, 8);
printf("入队后队列为:\n");
outputLinkQueue(tempQueuePtr);
printf("\n---- testLinkQueue 测试结束 ----\n");
}
/**
* @brief 主函数
*
* @return
*/
int main() {
testLinkQueue();
return 1;
}
1.2测试结果
---- testLinkQueue 测试开始 ----
10 入队
30 入队
50 入队
入队后队列为:
10 30 50
出队 得到 10
出队 得到 30
出队 得到 50
出队失败,队列为空.
出队 得到 -1
8 入队
入队后队列为:
8
---- testLinkQueue 测试结束 ----
1.3图解队列
2循环队列
2.1全部代码
#include <stdio.h>
#include <malloc.h>
#define TOTAL_SPACE 5
typedef struct CircleIntQueue{
int data[TOTAL_SPACE];
int head;
int tail;
}*CircleIntQueuePtr;
/**
* @brief 初始化队列
*
* @return
*/
CircleIntQueuePtr initQueue() {
CircleIntQueuePtr resultPtr = (CircleIntQueuePtr)malloc(sizeof(struct CircleIntQueue));
resultPtr->head = 0;
resultPtr->tail = 0;
return resultPtr;
}
/**
* @brief 入队
*
* @param paraPtr
* @param paraValue
*/
void enqueue(CircleIntQueuePtr paraPtr, int paraValue) {
if ((paraPtr->tail + 1) % TOTAL_SPACE == paraPtr->head) {
printf("入队失败,队满.\n");
return;
}
paraPtr->data[paraPtr->tail % TOTAL_SPACE] = paraValue;
paraPtr->tail++;
}
/**
* @brief 出队
*
* @param paraPtr
*
* @return
*/
int dequeue(CircleIntQueuePtr paraPtr) {
int resultValue;
if (paraPtr->head == paraPtr->tail) {
printf("出队失败,队空.\r\n");
return -1;
}
resultValue = paraPtr->data[paraPtr->head % TOTAL_SPACE];
paraPtr->head++;
return resultValue;
}
/**
* @brief 打印队列
*
* @param paraPtr
*/
void outputLinkQueue(CircleIntQueuePtr paraPtr){
int i;
if (paraPtr->head == paraPtr->tail) {
printf("打印队列失败,队空");
return;
}
printf("队中元素有: ");
for (i = paraPtr->head; i < paraPtr->tail; i++) {
printf("%d ", paraPtr->data[i % TOTAL_SPACE]);
}
printf("\n");
}
/**
* @brief 单元测试
*/
void testLinkQueue(){
printf("---- testLinkQueue 测试开始 ----\n");
int i = 10;
CircleIntQueuePtr tempPtr = initQueue();
for (; i < 16; i ++) {
enqueue(tempPtr, i);
}
outputLinkQueue(tempPtr);
for (i = 0; i < 6; i ++) {
int flag=dequeue(tempPtr);
if(flag==-1){
break;
}else printf("出队 得到%d\n", flag);
}
enqueue(tempPtr, 8);
outputLinkQueue(tempPtr);
printf("---- testLinkQueue 测试结束 ----\n");
}
int main(){
testLinkQueue();
return 1;
}
2.2测试结果
---- testLinkQueue 测试开始 ----
入队失败,队满.
入队失败,队满.
队中元素有: 10 11 12 13
出队 得到10
出队 得到11
出队 得到12
出队 得到13
出队失败,队空.
队中元素有: 8
---- testLinkQueue 测试结束 ----