赞
踩
1.一种特殊的线性表,只允许在一段进行插入,另一段进行删除;
2.进行插入操作的一端称为队尾,进行删除操作的一端称为队头;
3.队列具有先进先出的特性 FIFO(First In First Out)
队列总体来说是现实生活中的排队取号类似,先取票的,就先办理业务;队列中,先进入的,就先出去
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列类似顺序表头删数据,效率会比较低;此处我们就以链表结构实现队列举例:
1)结构定义:队列中我们在对头位置处队,对尾位置入队。为了便于操作,我们新建的一个结构体,用于存放队头、对尾位置的地址以及队中的数据个数。
typedef struct QueueNode {
QNDataType val;//数据域
struct QueueNode* next;//指针域
}QN;
typedef struct Queue {
QN* head;//头
QN* tail;//尾
int size;//有效数据个数,便于统计个数
}Queue;
2)初始化
// 初始化队列
void QueueInit(Queue* q) {
assert(q);
//初始队中无元素,队头、队尾都置为NULL
q->head = q->tail = NULL;
q->size = 0;
}
3)入队
// 入队 void QueuePush(Queue* q, QNDataType data) { assert(q); //创建新节点 QN* newNode = (QN*)malloc(sizeof(QN)); newNode->next = NULL; newNode->val = data; if (newNode == NULL) { perror("malloc"); } //第一个节点,要对头位置进行修改 if (q->head == NULL) { q->head = q->tail = newNode; } //其余位置都支对尾位置进行修改即可 else { q->tail->next = newNode; q->tail = newNode; } //有效数据个数加一 q->size++; }
4)出队
//出队 void QueuePop(Queue* q) { assert(q); //判空 assert(q->head); //仅有一个节点 if (q->head->next == NULL) { free(q->head); q->head = NULL; } //有两个或以上节点 else { QN* next = q->head->next; free(q->head); q->head = NULL; q->head = next; } q->size--; }
5)获取队头元素
// 获取队列头部元素
QNDataType QueueFront(Queue* q) {
assert(q);
assert(q->head);
return q->head->val;
}
6)获取队尾元素
// 获取队列队尾元素
QNDataType QueueBack(Queue* q) {
assert(q);
assert(q->head);
return q->tail->val;
}
7)获取队列中元素个数
// 获取队列中有效元素个数
int QueueSize(Queue* q) {
assert(q);
return q->size;
}
8)队列判空
// 检测队列是否为空
bool QueueEmpty(Queue* q) {
assert(q);
return q->head == NULL;
}
9)清空队列
//清空队列 void QueueClear(Queue* q) { assert(q); assert(q->head); //将队列中除首元素节点外的节点释放 QN* t = q->head->next; while (t) { QN* next = t->next; free(t); t = NULL; t = next; } //将头和尾节点置为NULL q->head = q->tail = NULL; }
10)销毁队列
// 销毁队列
void QueueDestroy(Queue* q) {
assert(q);
//将队列中所有空间释放
while (q->head) {
QN* next = q->head->next;
free(q->head);
q->head = NULL;
q->head = next;
}
q->size = 0;
}
1.Queue.h
#pragma once #include<stdio.h> #include<assert.h> #include<stdlib.h> #include<stdbool.h> typedef int QNDataType; typedef struct QueueNode { QNDataType val;//数据域 struct QueueNode* next;//指针域 }QN; typedef struct Queue { QN* head;//头 QN* tail;//尾 int size;//有效数据个数,便于统计个数 }Queue; // 初始化队列 void QueueInit(Queue* q); // 队尾入队列 void QueuePush(Queue* q, QNDataType data); // 队头出队列 void QueuePop(Queue* q); // 获取队列头部元素 QNDataType QueueFront(Queue* q); // 获取队列队尾元素 QNDataType QueueBack(Queue* q); // 获取队列中有效元素个数 int QueueSize(Queue* q); // 检测队列是否为空 bool QueueEmpty(Queue* q); //清空 void QueueClear(Queue*q); // 销毁队列 void QueueDestroy(Queue* q);
2.Queue.c
#pragma once #include"Queue.h" // 初始化队列 void QueueInit(Queue* q) { assert(q); //初始队中无元素,队头、队尾都置为NULL q->head = q->tail = NULL; q->size = 0; } // 入队 void QueuePush(Queue* q, QNDataType data) { assert(q); //创建新节点 QN* newNode = (QN*)malloc(sizeof(QN)); newNode->next = NULL; newNode->val = data; if (newNode == NULL) { perror("malloc"); } //第一个节点,要对头位置进行修改 if (q->head == NULL) { q->head = q->tail = newNode; } //其余位置都支对尾位置进行修改即可 else { q->tail->next = newNode; q->tail = newNode; } //有效数据个数加一 q->size++; } //出队 void QueuePop(Queue* q) { assert(q); //判空 assert(q->head); //仅有一个节点 if (q->head->next == NULL) { free(q->head); q->head = NULL; } //有两个或以上节点 else { QN* next = q->head->next; free(q->head); q->head = NULL; q->head = next; } q->size--; } // 获取队列头部元素 QNDataType QueueFront(Queue* q) { assert(q); assert(q->head); return q->head->val; } // 获取队列队尾元素 QNDataType QueueBack(Queue* q) { assert(q); assert(q->head); return q->tail->val; } // 获取队列中有效元素个数 int QueueSize(Queue* q) { assert(q); return q->size; } // 检测队列是否为空 bool QueueEmpty(Queue* q) { assert(q); return q->head == NULL; } //清空队列 void QueueClear(Queue* q) { assert(q); assert(q->head); //将队列中除首元素节点外的节点释放 QN* t = q->head->next; while (t) { QN* next = t->next; free(t); t = NULL; t = next; } //将头和尾节点置为NULL q->head = q->tail = NULL; } // 销毁队列 void QueueDestroy(Queue* q) { assert(q); //将队列中所有空间释放 while (q->head) { QN* next = q->head->next; free(q->head); q->head = NULL; q->head = next; } q->size = 0; }
3.Test.c
#define _CRT_SECURE_NO_WARNINGS #include"Queue.h" int main() { Queue q; QueueInit(&q); QueuePush(&q, 1); QueuePush(&q, 4); QueuePush(&q, 2); QueuePush(&q, 3); QueuePop(&q); int head = QueueFront(&q); printf("%d\n",head); int end = QueueBack(&q); printf("%d\n",end); int size = QueueSize(&q); printf("%d\n",size); bool ret1 = QueueEmpty(&q); if (ret1 == true) { printf("空\n"); } else { printf("非空\n"); } QueueClear(&q); bool ret2 = QueueEmpty(&q); if (ret2 == true) { printf("空\n"); } else { printf("非空\n"); } QueueDestroy(&q); return 0; }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。