C語(yǔ)言實(shí)現(xiàn)隊(duì)列的示例詳解
前言
前一段時(shí)間,我們?cè)囍肅語(yǔ)言實(shí)現(xiàn)了數(shù)據(jù)結(jié)構(gòu)中的順序表,單鏈表,雙向循環(huán)鏈表,棧。今天我們?cè)儆肅語(yǔ)言來(lái)實(shí)現(xiàn)另一種特殊的線(xiàn)性結(jié)構(gòu):隊(duì)列
一. 什么是隊(duì)列
隊(duì)列是一種特殊的線(xiàn)性表,特殊之處在于它只允許在表的前端(head)進(jìn)行刪除操作,而在表的后端(tail)進(jìn)行插入操作,和棧一樣,隊(duì)列是一種操作受限制的線(xiàn)性表。進(jìn)行插入操作的端稱(chēng)為隊(duì)尾,進(jìn)行刪除操作的端稱(chēng)為隊(duì)頭。
這個(gè)隊(duì)列就可以理解成我們平時(shí)的排隊(duì),先進(jìn)入的先出去,與我們之前實(shí)現(xiàn)的先進(jìn)后出的棧相反。
二. 使用什么來(lái)實(shí)現(xiàn)棧
再把上次的圖拿出來(lái),我們看看是用線(xiàn)性表來(lái)實(shí)現(xiàn)隊(duì)列,還是鏈表比較好
不同點(diǎn) | 順序表 | 鏈表 |
---|---|---|
存儲(chǔ)空間上 | 物理上一定連續(xù) | 邏輯上連續(xù),但物理上不一定連續(xù) |
隨機(jī)訪問(wèn) | 可以直接訪問(wèn)任何元素 | 必須從頭節(jié)點(diǎn)開(kāi)始往后尋找 |
任意位置插入或刪除元素 | 要搬移其他的元素,效率低。 | 只需要修改節(jié)點(diǎn)的指針指向,效率高 |
插入 | 動(dòng)態(tài)順序表,當(dāng)空間不夠時(shí)需要擴(kuò)容 | 無(wú)容量概念,需要就申請(qǐng),不用就釋放 |
應(yīng)用場(chǎng)景 | 元素高效存儲(chǔ),并且需要頻繁訪問(wèn) | 需要在任意位置插入或者刪除頻繁 |
綜合上表來(lái)看,我覺(jué)得鏈表較為方便,原因如下:
1.隊(duì)列有多少元素不確定,鏈表可以做到需要就申請(qǐng),不用就釋放,較為方便
2.隊(duì)列是先進(jìn)先出,順序固定,不需要隨機(jī)訪問(wèn)。
三. 隊(duì)列的實(shí)現(xiàn)
3.1頭文件
1.包含的標(biāo)準(zhǔn)庫(kù)
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <assert.h>
2.定義結(jié)構(gòu)體
typedef int QDateType;//隊(duì)列存儲(chǔ)數(shù)據(jù)類(lèi)型 typedef struct QueueNode //隊(duì)列元素節(jié)點(diǎn) { QDateType val; struct QueueNode* next; }QueueNode; typedef struct Queue //隊(duì)列 { QueueNode* head; QueueNode* tail; }Queue;
3.函數(shù)聲明
void QueueInti(Queue* pq); // 隊(duì)列初始化 void QueueDestory(Queue* pq); // 隊(duì)列的銷(xiāo)毀 void QueuePush(Queue* pq, QDateType x); // 入隊(duì) void QueuePop(Queue* pq); // 出隊(duì) QDateType QueueFront(Queue* pq); // 取出隊(duì)首元素 int QueueSize(Queue* pq); // 求隊(duì)列的長(zhǎng)度 bool QueueEmpty(Queue* pq); // 判斷隊(duì)是否為空
3.2 函數(shù)的實(shí)現(xiàn)
1.隊(duì)列的初始化
將頭尾置為空指針即可。
void QueueInti(Queue* pq) { assert(pq); //防止pq為空指針 pq->head = pq->tail = NULL; }
2.隊(duì)列的銷(xiāo)毀
遍歷隊(duì)列元素,然后將每一個(gè)元素釋放。
void QueueDestory(Queue* pq) { assert(pq); //防止pq為空指針 QueueNode* cur = pq->head; while (cur) { QueueNode* next = cur->next; free(cur); cur = next; } pq->tail = pq->head = NULL; }
3.入隊(duì)
對(duì)于入隊(duì),我們首先需要去開(kāi)辟一個(gè)新的節(jié)點(diǎn)來(lái)存儲(chǔ)數(shù)據(jù),然后將這個(gè)節(jié)點(diǎn)加入到tail后即可。此時(shí)我們就要分別考慮。
1.如果為空隊(duì)列,那么我們不僅要改變tail,還要改變head的值
2.如果不為空隊(duì)列,只用改變tail即可。
void QueuePush(Queue* pq, QDateType x) { assert(pq); //防止pq為空指針 QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode)); if (NULL == newNode) { printf("malloc error\n"); exit(-1); } newNode->val = x; newNode->next = NULL;//開(kāi)辟一個(gè)新節(jié)點(diǎn)存儲(chǔ)數(shù)據(jù) if (pq->tail == NULL)//判斷是否為空隊(duì)列 { assert(pq->head == NULL); pq->head = pq->tail = newNode; } else { pq->tail->next = newNode; pq->tail = newNode; } }
4.出隊(duì)
對(duì)于出隊(duì),我們同樣需要考慮兩種情況
- 隊(duì)列為空,改變head的同時(shí)改變tail
- 隊(duì)列不為空,改變head即可。
void QueuePop(Queue* pq) { assert(pq);//防止pq為空指針 assert(pq->head && pq->tail); //防止隊(duì)列為空隊(duì)列 if (pq->head->next == NULL) { free(pq->head); pq->head = pq->tail = NULL; } else { QueueNode* next = pq->head->next; free(pq->head); pq->head = next; } }
5. 取出隊(duì)首元素
沒(méi)啥說(shuō)的,直接訪問(wèn)頭節(jié)點(diǎn)取出即可
QDateType QueueFront(Queue* pq) { assert(pq);//防止pq為空指針 assert(pq->head && pq->tail); //防止隊(duì)列為空隊(duì)列 return pq->head->val; }
6.判斷是否為空隊(duì)列
我們只需要判斷頭指針是否為NULL,如果是則為空
bool QueueEmpty(Queue* pq) { assert(pq); return pq->head == NULL; }
7. 求隊(duì)伍長(zhǎng)度
創(chuàng)建一個(gè)變量,遍歷隊(duì)伍求長(zhǎng)度。
int QueueSize(Queue* pq) { assert(pq); QueueNode* cur = pq->head; int count = 0; while (cur) { cur = cur->next; count++; } return count; }
四.完整代碼
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <assert.h> typedef int QDateType; typedef struct QueueNode { QDateType val; struct QueueNode* next; }QueueNode; typedef struct Queue { QueueNode* head; QueueNode* tail; }Queue; void QueueInti(Queue* pq) { assert(pq); pq->head = pq->tail = NULL; } void QueueDestory(Queue* pq) { assert(pq); QueueNode* cur = pq->head; while (cur) { QueueNode* next = cur->next; free(cur); cur = next; } pq->tail = pq->head = NULL; } void QueuePush(Queue* pq, QDateType x) { assert(pq); QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode)); if (NULL == newNode) { printf("malloc error\n"); exit(-1); } newNode->val = x; newNode->next = NULL; if (pq->tail == NULL) { assert(pq->head == NULL); pq->head = pq->tail = newNode; } else { pq->tail->next = newNode; pq->tail = newNode; } } void QueuePop(Queue* pq) { assert(pq); assert(pq->head && pq->tail); if (pq->head->next == NULL) { free(pq->head); pq->head = pq->tail = NULL; } else { QueueNode* next = pq->head->next; free(pq->head); pq->head = next; } } bool QueueEmpty(Queue* pq) { assert(pq); return pq->head == NULL; } QDateType QueueFront(Queue* pq) { assert(pq); assert(pq->head); return pq->head->val; } int QueueSize(Queue* pq) { assert(pq); QueueNode* cur = pq->head; int count = 0; while (cur) { cur = cur->next; count++; } return count; }
以上就是C語(yǔ)言實(shí)現(xiàn)隊(duì)列的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于C語(yǔ)言 隊(duì)列的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++深入探究類(lèi)與對(duì)象之友元與運(yùn)算符重載
友元就是讓一個(gè)函數(shù)或者類(lèi),訪問(wèn)另一個(gè)類(lèi)中的私有成員;打個(gè)比方,這相當(dāng)于是說(shuō):朋友是值得信任的,所以可以對(duì)他們公開(kāi)一些自己的隱私,運(yùn)算符重載的實(shí)質(zhì)就是函數(shù)重載或函數(shù)多態(tài),運(yùn)算符重載是一種形式的C++多態(tài),目的在于讓人能夠用同名的函數(shù)來(lái)完成不同的基本操作2022-04-04C語(yǔ)言超詳細(xì)分析多進(jìn)程的概念與使用
在一個(gè)項(xiàng)目中并發(fā)執(zhí)行任務(wù)時(shí)多數(shù)情況下都會(huì)選擇多線(xiàn)程,但有時(shí)候也會(huì)選擇多進(jìn)程,例如可以同時(shí)運(yùn)行n個(gè)記事本編輯不同文本,由一個(gè)命令跳轉(zhuǎn)到另外一個(gè)命令,或者使用不同進(jìn)程進(jìn)行協(xié)作2022-08-08C++ OpenCV實(shí)現(xiàn)白平衡之灰度世界算法
灰度世界算法是白平衡各種算法中最基本的一種。本文將利用C++和OpenCV實(shí)現(xiàn)白平衡中的灰度世界算法,文中示例代碼講解詳細(xì),感興趣的可以了解一下2022-05-05C/C++代碼操作MySQL數(shù)據(jù)庫(kù)詳細(xì)步驟
這篇文章主要給大家介紹了關(guān)于C/C++代碼操作MySQL數(shù)據(jù)庫(kù)的相關(guān)資料,通過(guò)文中的這些示例,我們可以連接到MySQL數(shù)據(jù)庫(kù),并執(zhí)行常見(jiàn)的數(shù)據(jù)庫(kù)操作,如創(chuàng)建表、插入數(shù)據(jù)和查詢(xún)數(shù)據(jù),需要的朋友可以參考下2023-12-12關(guān)于vector迭代器失效的幾種情況總結(jié)
下面小編就為大家?guī)?lái)一篇關(guān)于vector迭代器失效的幾種情況總結(jié)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12C語(yǔ)言 一級(jí)指針與二級(jí)指針詳細(xì)介紹
這篇文章主要介紹了C語(yǔ)言 一級(jí)指針與二級(jí)指針詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2016-10-10