網站首頁 編程語言 正文
隊列的實現
隊列是一種先進先出(First in First Out)的線性表,簡稱FIFO。與棧不同,棧是一種后進先出(先進后出)的線性表。在隊列中,允許插入的一端稱為隊尾,允許刪除的一端稱為隊頭。假設隊列是q=(a1,a2,…,an),那么a1就是隊頭元素,而an是隊尾元素。這樣我們就可以刪除時,總是從a1開始,而插入時,列在最后。這也比較符合我們通常生活中的習慣,排在第一個的優先出列,最后來的當然在隊伍的最后。隊列分為順序隊列和循環隊列。順序隊列我們可以利用數組或者鏈表實現。這里,我們選擇用鏈表實現順序隊列。
今天主要介紹鏈表實現的隊列和循環隊列
鏈式隊列
隊列主要有哪些基本操作
// 初始化隊列
void QueueInit(Queue* q);
?
// 隊尾入隊列
void QueuePush(Queue* q, QDataType data);
// 隊頭出隊列
void QueuePop(Queue* q);
// 獲取隊列頭部元素
QDataType QueueFront(Queue* q);
// 獲取隊列隊尾元素
QDataType QueueBack(Queue* q);
// 獲取隊列中有效元素個數
int QueueSize(Queue* q);
// 檢測隊列是否為空,如果為空返回非零結果,如果非空返回0
bool QueueEmpty(Queue* q);
// 銷毀隊列
void QueueDestroy(Queue* q);
鏈式隊列的定義
typedef int QDataType;
// 鏈式結構:表示隊列
typedef struct QListNode
{
struct QListNode* _next;
QDataType _data;
}QNode;
?
// 隊列的結構
typedef struct Queue
{
QNode* _front;
QNode* _rear;
}Queue;
鏈式隊列的實現
1、初始化隊列
void QueueInit(Queue* q)
{
assert(q);
q->_front = NULL;
q->_rear = NULL;
}
2、銷毀隊列
void QueueDestroy(Queue* q)
{
assert(q);
QNode* cur = q->_front;
while (cur != NULL)
{
QNode* next = cur->_next;
free(cur);
cur = next;
}
q->_front = q->_rear = NULL;
}
3、隊列判空
bool QueueEmpty(Queue* q)
{
assert(q);
//if (q->_front == NULL)
//{
// return 1;
//}
//else
//{
// return 0;
//}
return q->_front == NULL;
}
4、入隊操作
void QueuePush(Queue* q, QDataType data)
{
assert(q);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
exit(-1);
}
newnode->_data = data;
newnode->_next = NULL;
if (q->_front == NULL)
{
q->_front = q->_rear = newnode;
}
else
{
q->_rear->_next = newnode;
q->_rear = newnode;
}
}
5、出隊操作
void QueuePop(Queue* q)
{
assert(q);
assert(!QueueEmpty(q));
QNode* next = q->_front->_next;
free(q->_front);
q->_front = next;
if (q->_front == NULL)
{
q->_rear = NULL;
}
}
6、取隊頭元素
QDataType QueueFront(Queue* q)
{
assert(q);
assert(!QueueEmpty(q));
return q->_front->_data;
}
7、取隊尾操作
QDataType QueueBack(Queue* q)
{
assert(q);
assert(!QueueEmpty(q));
return q->_rear->_data;
}
8、隊中有效元素個數
int QueueSize(Queue* q)
{
assert(q);
int size = 0;
QNode* cur = q->_front;
while (cur)
{
size++;
cur = cur->_next;
}
return size;
}
循環隊列
循環隊列的定義
循環隊列就是將隊列存儲空間的最后一個位置繞到第一個位置,形成邏輯上的環狀空間,供隊列循環使用。在循環隊列結構中,當存儲空間的最后一個位置已被使用而再要進入隊運算時,只需要存儲空間的第一個位置空閑,便可將元素加入到第一個位置,即將存儲空間的第一個位置作為隊尾。循環隊列可以更簡單防止偽溢出的發生,但隊列大小是固定的。在循環隊列中,當隊列為空時,有front=rear,而當所有隊列空間全占滿時,也有front=rear。為了區別這兩種情況,規定循環隊列最多只能有MaxSize-1個隊列元素,當循環隊列中只剩下一個空存儲單元時,隊列就已經滿了。因此,隊列判空的條件是front=rear,而隊列判滿的條件是front=(rear+1)%MaxSize。
循環隊列的空間可以重復利用,解決了普通隊列的空間浪費問題
循環隊列的實現
typedef struct {
int *a;
int front;
int tail;
int k;
} MyCircularQueue;
?
//提前聲明判空判滿
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);
//創建循環隊列
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* cq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
cq->a=(int*)malloc(sizeof(int)*(k+1));
cq->front=cq->tail=0;
cq->k=k;
return cq;
}
//循環隊列入隊
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(myCircularQueueIsFull(obj)){
return false;
}
obj->a[obj->tail]=value;
obj->tail++;
obj->tail%=(obj->k+1);
?
return true;
}
//循環隊列出隊
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj)){
return false;
}
obj->front++;
obj->front%=(obj->k+1);
return true;
?
}
//循環隊列取隊頭
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj)){
return -1;
}
return obj->a[obj->front];
}
//循環隊列取隊尾
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj)){
return -1;
}
int i=(obj->tail+obj->k)%(obj->k+1);
return obj->a[i];
}
//循環隊列判空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->front==obj->tail;
}
//循環隊列判滿
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->tail+1)%(obj->k+1)==obj->front;
}
//銷毀循環隊列
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
free(obj);
}
原文鏈接:https://blog.csdn.net/m0_52012656/article/details/121080208
相關推薦
- 2022-06-17 C語言深入講解函數參數的使用_C 語言
- 2024-01-06 RocketMQ消息丟失問題
- 2022-05-21 Python實現歸一化算法詳情_python
- 2022-12-26 層次分析法在matlab上的實現方式_python
- 2022-07-19 react組件通訊的三種方式props:父組件和子組件互相通訊、兄弟組件通訊
- 2022-05-17 springcloudgateway轉發websocket異常解決
- 2022-06-24 python類名和類方法cls修改類變量的值_python
- 2022-08-04 基于Python實現二維圖像雙線性插值_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支