先认识一下队列,它可以看作是平常排队,先进先出
一.链队列
1.代码
#include <stdio.h>
#include <malloc.h>
/*
创建节点
*/
typedef struct LinkNode {
int data;
struct LinkNode* next;
}*LinkNodePtr;
/*
队列结构
*/
typedef struct LinkQueue {
LinkNodePtr front;//头指针
LinkNodePtr rear;//尾指针
}*LinkQueuePtr;
/*
初始化
*/
LinkQueuePtr initQueue() {
LinkQueuePtr resultPtr = (LinkQueuePtr)malloc(sizeof(struct LinkQueue));
LinkNodePtr headerPtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
headerPtr->next = NULL;//创建头节点
resultPtr->front = headerPtr;
resultPtr->rear = headerPtr;
return resultPtr;
}
/*
输出队列
*/
void outputLinkQueue (LinkQueuePtr paraQueuePtr) {
LinkNodePtr tempPtr = paraQueuePtr->front->next;
while (tempPtr != NULL) {
printf("%d ", tempPtr->data);
tempPtr = tempPtr->next;
}//of while
printf("\r\n");
}
/*
入队
*/
void enqueue (LinkQueuePtr paraQueuePtr, int paraElement) {
//创建一个新节点
LinkNodePtr tempNodePtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
tempNodePtr->data = paraElement;
tempNodePtr->next = NULL;
//连接新节点
paraQueuePtr->rear->next = tempNodePtr;
//rear移动到新的尾节点
paraQueuePtr->rear = tempNodePtr;
}
/*
出队
*/
int dequeue (LinkQueuePtr paraQueuePtr) {
int resultValue;
LinkNodePtr tempNodePtr;
//判断队列是否为空
if (paraQueuePtr->front == paraQueuePtr->rear) {
printf("The queue is empty.\r\n");
return -1;
}//of if
//往后移动头指针
tempNodePtr = paraQueuePtr->front->next;
resultValue = tempNodePtr->data;
paraQueuePtr->front->next = paraQueuePtr->front->next->next;
//队列是否只剩一个元素
if (paraQueuePtr->rear == tempNodePtr) {
paraQueuePtr->rear = paraQueuePtr->front;
}//of if
//释放出队节点的空间
tempNodePtr = NULL;
return resultValue;
}
void testLinkQueue() {
LinkQueuePtr tempQueuePtr;
tempQueuePtr = initQueue();
enqueue(tempQueuePtr, 10);
enqueue(tempQueuePtr, 30);
enqueue(tempQueuePtr, 50);
outputLinkQueue(tempQueuePtr);
printf("dequeue gets %d\r\n", dequeue(tempQueuePtr));
printf("dequeue gets %d\r\n", dequeue(tempQueuePtr));
printf("dequeue gets %d\r\n", dequeue(tempQueuePtr));
printf("dequeue gets %d\r\n", dequeue(tempQueuePtr));
enqueue(tempQueuePtr, 8);
outputLinkQueue(tempQueuePtr);
}
int main() {
testLinkQueue();
return 1;
}
2.运行结果
3.图示
4.心得体会
①.链队列中多创建一个尾指针是避免遍历时额外花费时间,增加时间复杂度;
②.注意出队时需要释放节点;
③.与链表结构不同的是,增加了头指针和尾指针,用于入队和出队等操作。
二.循环队列
1.代码
#include <stdio.h>
#include <malloc.h>
#define TOTAL_SPACE 5
/*
创建队列结构
*/
typedef struct CircleIntQueue {
int data[TOTAL_SPACE];
int front;//头部
int rear;//尾部
}*CircleIntQueuePtr;
/*
初始化
*/
CircleIntQueuePtr initQueue() {
CircleIntQueuePtr resultPtr = (CircleIntQueuePtr)malloc(sizeof(struct CircleIntQueue));
resultPtr->front = 0;
resultPtr->rear = 0;
return resultPtr;
}
/*
入队
*/
void enqueue(CircleIntQueuePtr paraPtr, int paraValue) {
printf("Enqueue: %d ", paraValue);
//判断队列是否满了
if ((paraPtr->rear + 1) % TOTAL_SPACE == paraPtr->front) {
printf("Queue full.\r\n");
return;
}//of if
paraPtr->data[paraPtr->rear] = paraValue;
paraPtr->rear = (paraPtr->rear + 1) % TOTAL_SPACE;
}
/*
出队
*/
int dequeue(CircleIntQueuePtr paraPtr) {
int resultValue;
//判断队列是否为空
if (paraPtr->front == paraPtr->rear) {
printf("No element in the queue.\r\n");
return -1;
}//of if
resultValue = paraPtr->data[paraPtr->front];
paraPtr->front = (paraPtr->front + 1) % TOTAL_SPACE;
return resultValue;
}
/*
打印队列
*/
void outputCircleIntQueue(CircleIntQueuePtr paraPtr) {
int i;
//判断队列为空
if (paraPtr->front == paraPtr->rear) {
printf("Empty queue.");
return;
}//of if
printf("Element in the queue: ");
for (i = paraPtr->front; i != paraPtr->rear; i = (i + 1) % TOTAL_SPACE) {
printf("data[%d] = %d, ", i, paraPtr->data[i]);
}//of for
printf("\r\n");
}
void testCircleIntQueue() {
int i = 10;
CircleIntQueuePtr tempPtr = initQueue();
for (; i < 16; i ++) {
enqueue(tempPtr, i);
}//of for
outputCircleIntQueue(tempPtr);
for (i = 0; i < 6; i ++) {
printf("dequeue gets %d\r\n", dequeue(tempPtr));
}//of for
for (i = 3; i < 6; i ++) {
enqueue(tempPtr, i);
};
for (i = 20; i < 30; i ++) {
enqueue(tempPtr, i);
printf("dequeue gets %d\r\n", dequeue(tempPtr));
outputCircleIntQueue(tempPtr);
}//of for
}
int main() {
testCircleIntQueue();
return 1;
}
2.运行结果
3.图示
4.心得体会
①.循环队列好处是当出队时,前面空出来的位置仍可被使用,直到队列已满;
②.此处是rear尾部是指向最后一个元素,是
如果是指向最后一个元素的后一位,则两个代码位置调换