一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

深度解析數(shù)據(jù)結(jié)構(gòu)與算法篇之隊(duì)列及環(huán)形隊(duì)列的實(shí)現(xiàn)

Android編程精選 ? 來(lái)源:編程學(xué)習(xí)總站 ? 作者:寫代碼的牛頓 ? 2021-06-18 10:07 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

01

隊(duì)列簡(jiǎn)介

隊(duì)列是種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),有個(gè)元素進(jìn)入隊(duì)列稱為入對(duì)(enqueue),刪除元素稱為出隊(duì)(dequeue),隊(duì)列有對(duì)頭(head)和對(duì)尾(tail),當(dāng)有元素進(jìn)入隊(duì)列時(shí)就放在對(duì)尾的位置。

02

環(huán)形隊(duì)列的實(shí)現(xiàn)

要想將元素放入隊(duì)列我們必須知道對(duì)頭和隊(duì)尾,在隊(duì)列長(zhǎng)度不能無(wú)限大的條件下我們還要知道隊(duì)列的最大容量,我們還想知道隊(duì)列大小,所以隊(duì)列內(nèi)部能必須記錄當(dāng)前元素?cái)?shù)量。現(xiàn)在我們定義一個(gè)結(jié)構(gòu)體如下用于描述隊(duì)列。

#define NAN (0xFFFFFE) typedef struct queue_arr{ int head; int tail; int cap; int size; int *arr; }queue_arr_t;

head是對(duì)列頭,tail是對(duì)尾,cap記錄隊(duì)列的最大容量,size記錄當(dāng)前隊(duì)列大小,arr指針保存一塊內(nèi)存的首地址。下面我們定義隊(duì)列操作函數(shù)。

extern void queue_arr_init(queue_arr_t *q, int capacity); //隊(duì)列初始化 extern void enqueue_arr(queue_arr_t *q, int data); //入隊(duì) extern int dequeue_arr(queue_arr_t *q); //出隊(duì) extern void queue_arr_destroy(queue_arr_t *q); //銷毀隊(duì)列 extern bool queue_arr_is_full(queue_arr_t *q); //判斷隊(duì)列是否滿 extern bool queue_arr_is_empty(queue_arr_t *q); //判斷隊(duì)列是否為空 extern int queue_arr_length(queue_arr_t *q); //獲取隊(duì)列長(zhǎng)度

隊(duì)列初始化

void queue_arr_init(queue_arr_t *q, int capacity){ if(q == NULL || capacity 《= 0){ return; } q-》head = 0; q-》tail = 0; q-》size = 0; q-》arr = malloc(capacity * sizeof(int)); q-》cap = capacity; }

入隊(duì)

void enqueue_arr(queue_arr_t *q, int data){ if(q == NULL){ return; } if(queue_arr_is_full(q)){ return; } //循環(huán)重用使用過(guò)的內(nèi)存 if(q-》tail 》= q-》cap){ q-》tail = 0; } q-》arr[q-》tail++] = data; q-》size++; }

隊(duì)列容量有限,在進(jìn)行入隊(duì)前一定對(duì)隊(duì)列進(jìn)行判斷是否已滿。

出隊(duì)

int dequeue_arr(queue_arr_t *q){ if(q == NULL){ return NAN; } if(queue_arr_is_empty(q)){ return NAN; } if(q-》head 》= q-》cap){ q-》head = 0; } q-》size--; return q-》arr[q-》head++]; }

出隊(duì)時(shí)一定要對(duì)隊(duì)列進(jìn)行判斷是否已空。

判斷隊(duì)列是否已滿

bool queue_arr_is_full(queue_arr_t *q){ if(q == NULL){ return false; } return q-》size == q-》cap ? true : false; }

判斷隊(duì)列是否已空

bool queue_arr_is_empty(queue_arr_t *q){ if(q == NULL){ return true; } return q-》size == 0 ? true : false; }

獲取隊(duì)列長(zhǎng)度

int queue_arr_length(queue_arr_t *q){ if(q == NULL){ return 0; } return q-》size; }

銷毀隊(duì)列

void queue_arr_destroy(queue_arr_t *q){ if(q == NULL){ return; } if(q-》arr){ free(q-》arr); } q-》arr = NULL; q-》tail = 0; q-》head = 0; q-》cap = 0; q-》size = 0; }

03

鏈?zhǔn)疥?duì)列的實(shí)現(xiàn)

為了避免隊(duì)列元素的移動(dòng)我們實(shí)現(xiàn)了環(huán)形隊(duì)列,但是通過(guò)申請(qǐng)一塊內(nèi)存空間實(shí)現(xiàn)隊(duì)列在隊(duì)列大小未知的場(chǎng)景下無(wú)法滿足我們不斷加入元素進(jìn)入隊(duì)列的需求,這個(gè)時(shí)候就需要一種無(wú)需知道隊(duì)列的最大容量,且能動(dòng)態(tài)插入數(shù)據(jù)和取輸出的隊(duì)列實(shí)現(xiàn)。

我們知道鏈表能滿足這樣的需求,那么我們可以采用鏈表的實(shí)現(xiàn)方式實(shí)現(xiàn)隊(duì)列。下面我們分別定義一個(gè)結(jié)構(gòu)體用于描述鏈?zhǔn)疥?duì)列和隊(duì)列結(jié)點(diǎn)并聲明隊(duì)列操作函數(shù)。

typedef struct node{ int data; struct node *next; }node_t; typedef struct queue{ node_t *head; node_t *tail; }queue_t; extern void queue_init(queue_t *q); //隊(duì)列初始化 extern void enqueue(queue_t *q, int data); //數(shù)據(jù)入隊(duì) extern int dequeue(queue_t *q); //數(shù)據(jù)出隊(duì)列 extern int queue_length(queue_t *q); //獲取隊(duì)列長(zhǎng)度 extern void queue_destroy(queue_t *q); //銷毀隊(duì)列

隊(duì)列結(jié)點(diǎn)的next指針像單鏈表一樣指向下一個(gè)結(jié)點(diǎn),我們重點(diǎn)關(guān)注queue_t的定義,head是隊(duì)列頭,tail是對(duì)尾,有了對(duì)頭和對(duì)尾就能快速的從對(duì)尾插入數(shù)據(jù)從對(duì)頭取出數(shù)據(jù)。

隊(duì)列初始化

void queue_init(queue_t *q){ if(q == NULL){ return; } q-》head = NULL; q-》tail = NULL; }

入隊(duì)

元素每次進(jìn)入隊(duì)列都需要新建一個(gè)結(jié)點(diǎn),為了方便我們定義一個(gè)新建結(jié)點(diǎn)函數(shù)new_node,函數(shù)實(shí)現(xiàn)如下:

static node_t *new_node(int data){ node_t *node = (node_t *)malloc(sizeof(node_t)); if(node == NULL){ return NULL; } node-》next = NULL; node-》data = data; return node; }

入隊(duì)函數(shù)實(shí)現(xiàn)如下:

void enqueue(queue_t *q, int data){ if(q == NULL){ return; } node_t *node = new_node(data); //新建一個(gè)結(jié)點(diǎn) if(node == NULL){ return; } if(q-》head == NULL && q-》tail == NULL){ //首次插入一個(gè)結(jié)點(diǎn) q-》tail = node; q-》head = node; return; } q-》tail-》next = node; q-》tail = node; }

入隊(duì)前要進(jìn)行判斷隊(duì)列里是否有結(jié)點(diǎn),這里通過(guò)隊(duì)頭和對(duì)尾是否為空指針進(jìn)行判斷,如果隊(duì)列里沒(méi)有結(jié)點(diǎn)則直接將對(duì)頭和隊(duì)尾指向插入的結(jié)點(diǎn),否則結(jié)點(diǎn)則通過(guò)隊(duì)尾tail獲取到隊(duì)列最后的結(jié)點(diǎn),并將最后結(jié)點(diǎn)的next指針指向新插入的結(jié)點(diǎn),最后更新隊(duì)尾。

出隊(duì)

每次從隊(duì)列移除一個(gè)元素都需要釋放隊(duì)列結(jié)點(diǎn)內(nèi)存,為了方便我們定義一個(gè)是否結(jié)點(diǎn)內(nèi)存函數(shù),函數(shù)實(shí)現(xiàn)如下:

static void free_node(node_t *node){ if(node == NULL){ return; } free(node); node-》next = NULL; }

出隊(duì)函數(shù)實(shí)現(xiàn)如下:

int dequeue(queue_t *q){ if(q == NULL){ return NAN; } if(q-》head == NULL && q-》tail == NULL){ return NAN; } node_t *node = q-》head; int data = node-》data; if(q-》head-》next == q-》tail){ //只有一個(gè)結(jié)點(diǎn) q-》head = NULL; q-》tail = NULL; }else{ //不止一個(gè)結(jié)點(diǎn) q-》head = q-》head-》next; } node-》next = NULL; free_node(node); return data; }

出隊(duì)同樣要判斷隊(duì)列里是否有結(jié)點(diǎn),沒(méi)有結(jié)點(diǎn)則返回一個(gè)非法值,否則進(jìn)行判斷是否只有一個(gè)結(jié)點(diǎn),若只有一個(gè)結(jié)點(diǎn)則直接返回頭結(jié)點(diǎn),并將對(duì)頭和隊(duì)尾指針置為空指針,否則獲取隊(duì)列頭結(jié)點(diǎn)并更新對(duì)頭指針。

獲取隊(duì)列長(zhǎng)度

int queue_length(queue_t *q){ if(q == NULL){ return 0; } node_t *node = q-》head; if(node == NULL){ return 0; } int length = 1; while(node != q-》tail){ node = node-》next; length++; } return length; }

獲取隊(duì)列長(zhǎng)度只要從隊(duì)列頭結(jié)點(diǎn)不斷的遍歷隊(duì)列,判斷當(dāng)前結(jié)點(diǎn)是否已到隊(duì)列尾部,最后返回隊(duì)列長(zhǎng)度。

銷毀隊(duì)列

void queue_destroy(queue_t *q){ if(q == NULL){ return; } node_t *node = q-》head; if(node == NULL){ return; } node_t *temp = NULL; while(node-》next != q-》tail){ temp = node; node = node-》next; free_node(temp); temp = NULL; } free_node(node); q-》tail = NULL; q-》head = NULL; }

04

結(jié)果驗(yàn)證

下面我們寫一個(gè)小程序驗(yàn)證隊(duì)列實(shí)現(xiàn)是否正確。

#include 《stdio.h》 #include “queue.h” int main() { queue_t queue; int i = 0; queue_init(&queue); //隊(duì)列初始化 printf(“入隊(duì)順序 ”); for(i = 0; i 《 5; i++){ printf(“%d ,”, i + 1); enqueue(&queue, i + 1); } printf(“ ”); printf(“隊(duì)列長(zhǎng)度: %d ”, queue_length(&queue)); printf(“取出隊(duì)列一個(gè)數(shù)據(jù):%d ”, dequeue(&queue)); printf(“取出隊(duì)列一個(gè)數(shù)據(jù):%d ”, dequeue(&queue)); printf(“隊(duì)列長(zhǎng)度: %d ”, queue_length(&queue)); printf(“銷毀隊(duì)列 ”); queue_destroy(&queue); printf(“ ”); printf(“大小固定的隊(duì)列測(cè)試 ”); queue_arr_t queue2; queue_arr_init(&queue2, 6); printf(“入隊(duì)順序 ”); for(i = 10; i 《 16; i++){ printf(“%d ,”, i); enqueue_arr(&queue2, i); } printf(“ ”); if(queue_arr_is_full(&queue2)){ printf(“隊(duì)列已滿 ”); }else{ printf(“隊(duì)列未滿 ”); } printf(“取出隊(duì)列一個(gè)數(shù)據(jù):%d ”, dequeue_arr(&queue2)); printf(“取出隊(duì)列一個(gè)數(shù)據(jù):%d ”, dequeue_arr(&queue2)); if(queue_arr_is_full(&queue2)){ printf(“隊(duì)列已滿 ”); }else{ printf(“隊(duì)列未滿 ”); } printf(“隊(duì)列長(zhǎng)度是:%d ”, queue_arr_length(&queue2)); printf(“銷毀隊(duì)列 ”); queue_arr_destroy(&queue2); if(queue_arr_is_empty(&queue2)){ printf(“隊(duì)列已空 ”); }else{ printf(“隊(duì)列未空 ”); } return 0; }

編譯輸出如下:

入隊(duì)順序 1 ,2 ,3 ,4 ,5 , 隊(duì)列長(zhǎng)度: 5 取出隊(duì)列一個(gè)數(shù)據(jù):1 取出隊(duì)列一個(gè)數(shù)據(jù):2 隊(duì)列長(zhǎng)度: 3 銷毀隊(duì)列 大小固定的隊(duì)列測(cè)試 入隊(duì)順序 10 ,11 ,12 ,13 ,14 ,15 , 隊(duì)列已滿 取出隊(duì)列一個(gè)數(shù)據(jù):10 取出隊(duì)列一個(gè)數(shù)據(jù):11 隊(duì)列未滿 隊(duì)列長(zhǎng)度是:4 銷毀隊(duì)列 隊(duì)列已空

輸出完全正確。

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7256

    瀏覽量

    91894
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4381

    瀏覽量

    64904

原文標(biāo)題:數(shù)據(jù)結(jié)構(gòu)與算法篇-隊(duì)列

文章出處:【微信號(hào):AndroidPush,微信公眾號(hào):Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    RabbitMQ消息隊(duì)列解決方案

    在現(xiàn)代分布式系統(tǒng)架構(gòu)中,消息隊(duì)列作為核心組件,承擔(dān)著系統(tǒng)解耦、異步處理、流量削峰等重要職責(zé)。RabbitMQ作為一款成熟的消息隊(duì)列中間件,以其高可用性、高可靠性和豐富的特性,成為眾多企業(yè)的首選方案。本文將從運(yùn)維工程師的角度,詳細(xì)闡述RabbitMQ從單機(jī)部署到集群搭建的完
    的頭像 發(fā)表于 07-08 15:55 ?190次閱讀

    精通 MQTT:消息隊(duì)列遙測(cè)傳輸指南!

    引言MQTT(消息隊(duì)列遙測(cè)傳輸)是一種輕量級(jí)消息協(xié)議,專為低帶寬、高延遲和不可靠的網(wǎng)絡(luò)環(huán)境設(shè)計(jì)。它廣泛應(yīng)用于物聯(lián)網(wǎng)(IoT)應(yīng)用、消息系統(tǒng)以及實(shí)時(shí)數(shù)據(jù)通信領(lǐng)域。本指南深入探討了MQTT的工作原理
    的頭像 發(fā)表于 06-16 16:56 ?485次閱讀
    精通 MQTT:消息<b class='flag-5'>隊(duì)列</b>遙測(cè)傳輸指南!

    RDMA簡(jiǎn)介5RoCE V2隊(duì)列分析

    在RoCE v2協(xié)議中,RoCE v2隊(duì)列數(shù)據(jù)傳輸?shù)淖畹讓涌刂茩C(jī)制,其由工作隊(duì)列(WQ)和完成隊(duì)列(CQ)共同組成。其中工作隊(duì)列采用雙向通
    發(fā)表于 06-05 17:28

    程序設(shè)計(jì)與數(shù)據(jù)結(jié)構(gòu)

    的地址)出發(fā),采用推導(dǎo)的方式,深入淺出的分析了廣大C程序員學(xué)習(xí)和開(kāi)發(fā)中遇到的難點(diǎn)。 2. 從方法論的高度對(duì)C語(yǔ)言在數(shù)據(jù)結(jié)構(gòu)算法方面的應(yīng)用進(jìn)行了深入講解和闡述。 3. 講解了絕大多數(shù)C程序員開(kāi)發(fā)
    發(fā)表于 05-13 16:45

    NVME控制器隊(duì)列管理模塊

    隊(duì)列管理模塊是整個(gè)NVMe Host控制器的核心模塊,該模塊實(shí)現(xiàn)了提交隊(duì)列與完成隊(duì)列的管理,多隊(duì)列請(qǐng)求的仲裁判決等功能。
    發(fā)表于 05-03 20:19

    NVME控制器隊(duì)列管理模塊

    隊(duì)列管理模塊是整個(gè)NVMe Host控制器的核心模塊,該模塊實(shí)現(xiàn)了提交隊(duì)列與完成隊(duì)列的管理,多隊(duì)列請(qǐng)求的仲裁判決等功能。
    的頭像 發(fā)表于 05-03 15:32 ?191次閱讀
    NVME控制器<b class='flag-5'>之</b><b class='flag-5'>隊(duì)列</b>管理模塊

    NVME控制器設(shè)計(jì)1

    管理。NVMe隊(duì)列實(shí)現(xiàn) NVMe指令提交與完成機(jī)制的核心組件, 隊(duì)列的數(shù)量和深度直接影響數(shù)據(jù)傳輸?shù)男阅堋?在小
    發(fā)表于 04-24 09:45

    Linux進(jìn)程狀態(tài)詳解

    對(duì)應(yīng)設(shè)備未就緒那么進(jìn)程就要阻塞等待了。進(jìn)程狀態(tài)變化的表現(xiàn)之一就是要在不同的隊(duì)列中進(jìn)行流動(dòng),本質(zhì)都是數(shù)據(jù)結(jié)構(gòu)的增刪查改!
    的頭像 發(fā)表于 04-01 09:46 ?446次閱讀
    Linux進(jìn)程狀態(tài)詳解

    JavaWeb消息隊(duì)列使用指南

    在現(xiàn)代的JavaWeb應(yīng)用中,消息隊(duì)列(Message Queue)是一種常見(jiàn)的技術(shù),用于異步處理任務(wù)、解耦系統(tǒng)組件、提高系統(tǒng)性能和可靠性。 1. 消息隊(duì)列的基本概念 消息隊(duì)列是一種應(yīng)用程序?qū)?yīng)
    的頭像 發(fā)表于 11-25 09:27 ?533次閱讀

    探索字節(jié)隊(duì)列的魔法:多類型支持、函數(shù)重載與線程安全

    數(shù)據(jù)結(jié)構(gòu),它能夠高效地存儲(chǔ)和管理數(shù)據(jù)流。通過(guò)使用字節(jié)隊(duì)列,我們可以靈活地處理不同類型的數(shù)據(jù)、確保數(shù)據(jù)的完整性,并在多線程環(huán)境中安全地進(jìn)行操
    的頭像 發(fā)表于 11-15 01:08 ?1245次閱讀
    探索字節(jié)<b class='flag-5'>隊(duì)列</b>的魔法:多類型支持、函數(shù)重載與線程安全

    為什么同一個(gè)隊(duì)列引用的全局變量,運(yùn)行在兩個(gè)子vi中發(fā)現(xiàn)隊(duì)列數(shù)據(jù)丟失了

    我創(chuàng)建了一個(gè)隊(duì)列,然后將隊(duì)列引用做了個(gè)全局變量,運(yùn)行在兩個(gè)子vi中,一個(gè)是只入隊(duì)列,另一個(gè)是只出隊(duì)列。但我發(fā)現(xiàn),一個(gè)字vi數(shù)據(jù)
    發(fā)表于 11-14 11:47

    視覺(jué)軟件HALCON的數(shù)據(jù)結(jié)構(gòu)

    在研究機(jī)器視覺(jué)算法之前,我們需要先了解機(jī)器視覺(jué)應(yīng)用中涉及的基本數(shù)據(jù)結(jié)構(gòu)。Halcon數(shù)據(jù)結(jié)構(gòu)主要有圖像參數(shù)和控制參數(shù)兩類參數(shù)。圖像參數(shù)包括:image、region、XLD,控制參數(shù)包括:string、integer、real、
    的頭像 發(fā)表于 11-14 10:20 ?1297次閱讀
    視覺(jué)軟件HALCON的<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>

    嵌入式環(huán)形隊(duì)列與消息隊(duì)列實(shí)現(xiàn)原理

    嵌入式環(huán)形隊(duì)列,也稱為環(huán)形緩沖區(qū)或循環(huán)隊(duì)列,是一種先進(jìn)先出(FIFO)的數(shù)據(jù)結(jié)構(gòu),用于在固定大小的存儲(chǔ)區(qū)域中高效地存儲(chǔ)和訪問(wèn)
    的頭像 發(fā)表于 09-02 15:29 ?1261次閱讀

    嵌入式常用數(shù)據(jù)結(jié)構(gòu)有哪些

    在嵌入式編程中,數(shù)據(jù)結(jié)構(gòu)的選擇和使用對(duì)于程序的性能、內(nèi)存管理以及開(kāi)發(fā)效率都具有重要影響。嵌入式系統(tǒng)由于資源受限(如處理器速度、內(nèi)存大小等),因此對(duì)數(shù)據(jù)結(jié)構(gòu)的選擇和使用尤為關(guān)鍵。以下是嵌入式編程中常用的幾種數(shù)據(jù)結(jié)構(gòu),結(jié)合具體特點(diǎn)和
    的頭像 發(fā)表于 09-02 15:25 ?1042次閱讀

    玩轉(zhuǎn)RT-Thread消息隊(duì)列的應(yīng)用

    不同來(lái)源的數(shù)據(jù),確保系統(tǒng)的穩(wěn)定性和響應(yīng)速度。一、設(shè)計(jì)消息結(jié)構(gòu)二、創(chuàng)建消息隊(duì)列在service.c文件中,我們需要?jiǎng)?chuàng)建一個(gè)消息隊(duì)列來(lái)存放這些消息,并在處理線程中接收和
    的頭像 發(fā)表于 07-23 08:11 ?916次閱讀
    玩轉(zhuǎn)RT-Thread<b class='flag-5'>之</b>消息<b class='flag-5'>隊(duì)列</b>的應(yīng)用