單鏈表實現【隊列】

目錄

隊列的概念及其結構

隊列的實現

數組隊列

鏈式隊列

隊列的常見接口的實現

主函數Test.c

頭文件&函數聲明Queue.h

頭文件

函數聲明

函數實現Queue.c

初始化QueueInit

創建節點Createnode?

空間釋放QueueDestroy

入隊列QueuePush

出隊列QueuePop

隊頭元素QueueFront

隊尾元素QueueBack

判斷隊列是否為空QueueEmpty

隊列元素個數QueueSize

鏈式隊列總代碼


隊列的概念及其結構

隊列:只允許在一端進行插入數據操作,在另一端進行刪除數據操作的特殊線性表。

隊列具有 先進先出 /后進后出 FIFO(First In First Out)

入隊列:進行插入操作的一端稱為 隊尾。

出隊列:進行刪除操作的一端稱為 隊頭。

隊列的實現

隊列的實現也有兩種方式。隊列也可以數組和鏈表的結構實現,使用鏈表的結構實現更優一些,因為如果使用數組的結構,出隊列在數組頭上出數據,效率會比較低

數組隊列

雖然數組也可以實現【隊列】,但是挪動數據的效率真的很低!!?

鏈式隊列

無論是【棧】還是【隊列】雙向鏈表都是通吃的。但是我們為了節省資源就是要用【單鏈表】去實現隊列。我們用【單鏈表】去實現【隊列】需要注意:

  • 入隊列 == 尾插
  • 出隊列 == 頭刪
  • 需要ptail指針維護隊列最后一個元素
  • 需要phead指針維護隊列最后一個元素
  • 二級指針&一級指針
  • 帶不帶哨兵位的頭節點都可(哨兵位的頭節點最后要釋放空間)

應用場景:辦理業務排隊打號機。因為【隊列】是絕對公平的。

隊列的常見接口的實現

  • 入隊列和出隊列的順序都只有一種!!
  • 傳二級指針/傳一級指針的情況
  • 怎么去計算隊列元素個數?
  • 怎么用其他方式替代傳二級指針?空間換時間的方式
  • 鏈表都需要考慮?鏈表沒有元素?鏈表只有一個元素//兩種情況即對應指針的判斷情況
  • 二級指針 == 頭節點 == 返回值 == 結構體包含兩個一級指針?

主函數Test.c

#include"Queue.h"
int main()
{Queue pq;QueueInit(&pq);QueuePush(&pq, 1);QueuePush(&pq, 2);QueuePush(&pq, 3);QueuePush(&pq, 4);QueuePush(&pq, 77);QueuePush(&pq, 7);while (!QueueEmpty(&pq)){printf("隊頭元素:%d\n", QueueFront(&pq));//printf("隊尾元素:%d\n", QueueBack(&pq));QueuePop(&pq);}QueueDestroy(&pq);return 0;
}

頭文件&函數聲明Queue.h

頭文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

函數聲明

  • 創建節點
typedef int QDataType;
//創建隊列節點
typedef struct QueueNode
{QDataType val;struct QueueNode* next;//易錯?QNode*next
}QNode;
  • 創建維護隊列的指針
//兩個指針維護鏈表隊列
typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;
  • 初始化
void QueueInit(Queue* pq);
  • 銷毀釋放空間
void QueueDestroy(Queue* pq);
  • 入隊列
void QueuePush(Queue* pq, QDataType x);
  • 出隊列
void QueuePop(Queue* pq);
  • 隊頭元素
QDataType QueueFront(Queue* pq);
  • 隊尾元素
QDataType QueueBack(Queue* pq);
  • 判斷隊列是否為空
bool QueueEmpty(Queue* pq);
  • 隊列元素個數
int QueueSzie(Queue* pq);

函數實現Queue.c

初始化QueueInit

#include"Queue.h"
//不需要頭節點,初始化
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}

創建節點Createnode?

Queue* Createnode(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("fail malloc");return;}newnode->val = x;newnode->next = NULL;return newnode;
}

空間釋放QueueDestroy

//空間釋放
void QueueDestroy(Queue* pq)
{assert(pq);while (pq->phead){Queue* cur = pq->phead;pq->phead = pq->phead->next;free(cur);cur = NULL;}pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}

入隊列QueuePush

//Push元素
void QueuePush(Queue* pq, QDataType x)
{assert(pq);//創建節點Queue* newnode = Createnode(pq,x);if (pq->phead == NULL){pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}

出隊列QueuePop

  • 刪到空的情況(phead/ptail野指針的情況)
  • 刪到只剩一個節點的情況(ptail野指針的情況)
//Pop元素
void QueuePop(Queue* pq)
{assert(pq);assert(pq->size > 0);//為NULL的判斷Queue* cur = pq->phead;pq->phead = pq->phead->next;free(cur);cur = NULL;//為一個節點的判斷if (pq->phead == NULL){pq->ptail = NULL;}pq->size--;
}

隊頭元素QueueFront

//隊頭元素
QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->size > 0);return pq->phead->val;
}

隊尾元素QueueBack

//隊尾元素
QDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->size > 0);return pq->ptail->val;
}

判斷隊列是否為空QueueEmpty

//判斷是否為NULL
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}

隊列元素個數QueueSize

//隊員元素個數
int QueueSzie(Queue* pq)
{assert(pq);return pq->size;
}

鏈式隊列總代碼

//Test.c
#include"Queue.h"
int main()
{Queue pq;QueueInit(&pq);QueuePush(&pq, 1);QueuePush(&pq, 2);QueuePush(&pq, 3);QueuePush(&pq, 4);QueuePush(&pq, 77);QueuePush(&pq, 7);while (!QueueEmpty(&pq)){printf("隊頭元素:%d\n", QueueFront(&pq));//printf("隊尾元素:%d\n", QueueBack(&pq));QueuePop(&pq);}QueueDestroy(&pq);return 0;
}
//Queue.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>typedef int QDataType;
//創建隊列節點
typedef struct QueueNode
{QDataType val;struct QueueNode* next;//易錯?QNode*next
}QNode;
//兩個指針維護鏈表隊列
typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;
//接口的實現
void QueueInit(Queue* pq);//初始化
void QueueDestroy(Queue* pq);//空間釋放
void QueuePush(Queue* pq, QDataType x);//放元素到隊列尾
void QueuePop(Queue* pq);//出元素到隊頭
QDataType QueueFront(Queue* pq);//隊列頭的元素
QDataType QueueBack(Queue* pq);//隊列尾的元素
bool QueueEmpty(Queue* pq);//判斷隊列是否是否為NULL
int QueueSzie(Queue* pq);//隊列里面的元素個數
//Queue.c
#include"Queue.h"
//不需要頭節點,初始化
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}Queue* Createnode(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("fail malloc");return;}newnode->val = x;newnode->next = NULL;return newnode;
}
//Push元素
void QueuePush(Queue* pq, QDataType x)
{assert(pq);//創建節點Queue* newnode = Createnode(pq,x);if (pq->phead == NULL){pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}//Pop元素
void QueuePop(Queue* pq)
{assert(pq);assert(pq->size > 0);//為NULL的判斷Queue* cur = pq->phead;pq->phead = pq->phead->next;free(cur);cur = NULL;//為一個節點的判斷if (pq->phead == NULL){pq->ptail = NULL;}pq->size--;
}//隊頭元素
QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->size > 0);return pq->phead->val;
}//隊尾元素
QDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->size > 0);return pq->ptail->val;
}//判斷是否為NULL
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}//隊員元素個數
int QueueSzie(Queue* pq)
{assert(pq);return pq->size;
}//空間釋放
void QueueDestroy(Queue* pq)
{assert(pq);while (pq->phead){Queue* cur = pq->phead;pq->phead = pq->phead->next;free(cur);cur = NULL;}pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}

?????最后,感謝大家的閱讀,若有錯誤和不足,歡迎指正!下篇博文會分享一些【棧和隊列的OJ題目】&【循環隊列】各位小伙伴乖乖敲代碼哦。?

代碼---------→【唐棣棣 (TSQXG) - Gitee.com】

聯系---------→【郵箱:2784139418@qq.com】

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164603.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164603.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164603.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Hyper-V系列:Hyper-V啟動、創建虛擬機、與主機傳輸文件

Hyper-V啟動、創建虛擬機、與主機傳輸文件 一. 簡介二. 啟用Hyper-V的方式也很簡單:一、從“任務管理器”的“性能”查看虛擬化是否啟用,未啟用的需要到BIOS開啟:右下角可以看到“虛擬化:已啟用”二、啟用Hyper-v和虛擬機1.電腦左下角右鍵打開應用界面——可選功能2.在可選…

JavaScript 原始數據類型和對應的對象類型(內置對象)之間的關系

JavaScript 原始數據類型和對應的對象類型&#xff08;內置對象&#xff09;之間的關系 JavaScript 的原始&#xff08;primitive&#xff09;數據類型包括包括數字&#xff08;Number&#xff09;、字符串&#xff08;String&#xff09;、布爾值&#xff08;Boolean&#xf…

【數據結構】E : 貨幣套匯(圖路徑)

E : 貨幣套匯&#xff08;圖路徑&#xff09; Description 套匯是指利用貨幣匯兌率的差異將一個單位的某種貨幣轉換為大于一個單位的同種貨幣。例如&#xff0c;假定1 美元可以買0.7 英鎊&#xff0c;1 英鎊可以買9.5 法郎&#xff0c;1法郎可以買到0.16美元。通過貨幣兌換&a…

ELK企業級日志分析平臺——ES集群監控

啟用xpack認證 官網&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/7.6/configuring-tls.html#node-certificates 在elk1上生成證書 [rootelk1 ~]# cd /usr/share/elasticsearch/[rootelk1 elasticsearch]# bin/elasticsearch-certutil ca[rootelk1 ela…

GB/T 29498-2013 木門窗檢測

木門窗是指以木材、木質復合材料為主要材料制作框和扇的門窗。 GB/T 29498-2013 木門窗檢測項目 測試項目 測試標準 外觀質量 GB/T 29498 尺寸 GB/T 29498 裝配質量 GB/T 29498 含水率 GB/T 17657 附著力 GB/T 4893.4 外門窗耐冷熱循環 GB/T 4893.7 耐劃痕 GB/…

Volcano3D繪制3D火山圖

一邊學習&#xff0c;一邊總結&#xff0c;一邊分享&#xff01; 本期教程內容 **注&#xff1a;**本教程詳細內容 Volcano3D繪制3D火山圖 一、前言 火山圖是做差異分析中最常用到的圖形&#xff0c;在前面的推文中&#xff0c;我們也推出了好幾期火山圖的繪制教程&#xff0…

【代數學習題4.2】從零理解范數與跡 —— 求數域元素的范數與跡

從零理解范數與跡 —— 求數域元素的范數與跡 寫在最前面題目解答 2. 范數 N N N思路求解過程python求解 3. 數域 K K K 的范數 N K N_K NK?思路求解過程Python求解分析解題步驟 4. 跡 T T T求解過程共軛元素計算跡 python求解分析解題步驟 5. 數域 K K K 的跡 T K T_K …

讀書筆記——《黑猩猩的政治》

前言 弗朗斯德瓦爾&#xff08;Frans de Waal)的代表作《黑猩猩政治》成書于1982年&#xff0c;是它的首部書籍作品&#xff0c;也是美國國會新任議員的被推薦讀物。之前看的他另一部作品的《萬智有靈》是2016年的作品&#xff0c;時間跨度居然這么大。《萬智有靈》介紹了許多…

代碼隨想錄 135. 分發糖果

題目 n 個孩子站成一排。給你一個整數數組 ratings 表示每個孩子的評分。 你需要按照以下要求&#xff0c;給這些孩子分發糖果&#xff1a; 每個孩子至少分配到 1 個糖果。 相鄰兩個孩子評分更高的孩子會獲得更多的糖果。 請你給每個孩子分發糖果&#xff0c;計算并返回需要準…

SDK廣告類型及其作用與收益分析

在移動應用開發領域&#xff0c;軟件開發工具包&#xff08;SDK&#xff09;廣告已經成為應用開發者們獲取收益的一種重要途徑。不同類型的SDK廣告提供了多樣化的選擇&#xff0c;以滿足開發者的需求。本文將介紹幾種常見的SDK廣告類型&#xff0c;并深入探討它們的作用及對開發…

SPASS-信度分析

信度分析概述 效度 效度指的是量表是否真正反映了我們希望測量的東西。一般來說&#xff0c;有4種類型的效度&#xff1a;內容效度、標準效度、結構效度和區分效度。內容效度是一種基于概念的評價指標&#xff0c;其他三種效度是基于經驗的評價指標。如果一個量表實際上是有效…

【亞太杯前兩問論文】2023年第十三屆APMCM亞太地區大學生數學建模競賽——(文末領取方式)

2023年第十三屆APMCM亞太地區大學生數學建模競賽——論文無償分享&#xff01;&#xff01;&#xff01; C題前兩問論文代碼已出&#xff0c;其他賽題及后續論文代碼會持續更新。 祝各位小伙伴都能在比賽中發揮出色&#xff0c;取得心儀的成績呦&#xff01;一起加油&#xff…

vscode在運行c語言時,無法scanf輸入

問題&#xff1a; 在學習c語言中&#xff0c;我在使用scanf和cin時無法在終端進行輸入(運行了但是無法輸入)&#xff0c;在網上尋找答案&#xff0c;并寫下筆記 解決方法 選擇左上角 文件->首選項&#xff08;preferences&#xff09;->設置&#xff08;settings&#xf…

網關和鏈路追蹤

Spring Cloud的網關 在Spring Cloud中&#xff0c;網關&#xff08;Gateway&#xff09;是一種用于管理和路由微服務請求的中間層服務。它充當了整個微服務架構的入口點&#xff0c;負責將來自外部的請求轉發到相應的微服務上。常見的網關包括Spring Cloud Gateway和Netflix Zu…

Java類加載那些事

Java源文件&#xff08;.java文件&#xff09;被編譯器編譯后變為字節碼形式的類文件&#xff08;.class文件&#xff09;&#xff0c;Java類加載的過程就是JVM加載.class的二進制文件并且放到內存中&#xff0c;將數據放到方法區&#xff0c;并且在堆區構造一個java.lang.clas…

動態規劃從入門到精通

目錄 動態規劃的詳解 動態規劃的應用 機器人到達指定位置數 換錢的最少貨幣數 排成一條線的紙牌博弈問題 象棋中馬的跳法 Bob的生存概率 換錢的方法數 動態規劃的總結 動態規劃的詳解 暴力嘗試遞歸操作中有很多重復計算的操作&#xff0c;浪費時間。動態規劃就是減少暴力…

大模型增量預訓練參數說明

在增量預訓練過程中通常需要設置三類或四類參數,模型參數,數據參數,訓練參數,額外參數。 下面分別針對這四種參數進行說明。 歡迎關注公眾號 模型參數 model_type模型類型,例如bloom,llama,baichuan,qwen等。 model_name_or_path模型名稱或者路徑。 tokenizer_name_or…

JS數組常用的20種方法詳解(每一個方法都有例子,超全面,超好理解的教程,干貨滿滿)

目錄 1.會改變原數組的方法&#xff08;7種&#xff09; 1.push() 2.pop() 3.unshift() 4.shift() 5.reverse() 6.sort() 7.splice() 2.不改變原數組的方法&#xff08;13種&#xff0c;返回的新數組是從原數組淺拷貝來的&#xff09; 1.concat() 2.join() 3.slice…

12個最佳WordPress投票插件

您是否正在為您的網站尋找WordPress投票插件&#xff1f; WordPress投票插件可讓您輕松地在您的網站上進行民意調查&#xff0c;用戶可以投票。這是在收集見解的同時建立用戶參與度的有效策略。 在本文中&#xff0c;我們精心挑選了最好的WordPress投票插件&#xff0c;可幫助…

代碼隨想錄算法訓練營第五十二天|300.最長遞增子序列 674. 最長連續遞增序列 718. 最長重復子數組

文檔講解&#xff1a;代碼隨想錄 視頻講解&#xff1a;代碼隨想錄B站賬號 狀態&#xff1a;看了視頻題解和文章解析后做出來了 300.最長遞增子序列 class Solution: # 2516 ms, faster than 64.96%def lengthOfLIS(self, nums: List[int]) -> int:n len(nums)dp [1] * n…