日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

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

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

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

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

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

掃碼添加小助手

加入工程師交流群

01

隊(duì)列簡介

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

02

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

要想將元素放入隊(duì)列我們必須知道對頭和隊(duì)尾,在隊(duì)列長度不能無限大的條件下我們還要知道隊(duì)列的最大容量,我們還想知道隊(duì)列大小,所以隊(duì)列內(nèi)部能必須記錄當(dāng)前元素數(shù)量?,F(xiàn)在我們定義一個結(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是對列頭,tail是對尾,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ì)列長度

隊(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)重用使用過的內(nèi)存 if(q-》tail 》= q-》cap){ q-》tail = 0; } q-》arr[q-》tail++] = data; q-》size++; }

隊(duì)列容量有限,在進(jìn)行入隊(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ì)時一定要對隊(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ì)列長度

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ì)列元素的移動我們實(shí)現(xiàn)了環(huán)形隊(duì)列,但是通過申請一塊內(nèi)存空間實(shí)現(xiàn)隊(duì)列在隊(duì)列大小未知的場景下無法滿足我們不斷加入元素進(jìn)入隊(duì)列的需求,這個時候就需要一種無需知道隊(duì)列的最大容量,且能動態(tài)插入數(shù)據(jù)和取輸出的隊(duì)列實(shí)現(xiàn)。

我們知道鏈表能滿足這樣的需求,那么我們可以采用鏈表的實(shí)現(xiàn)方式實(shí)現(xiàn)隊(duì)列。下面我們分別定義一個結(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ì)列長度 extern void queue_destroy(queue_t *q); //銷毀隊(duì)列

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

隊(duì)列初始化

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

入隊(duì)

元素每次進(jìn)入隊(duì)列都需要新建一個結(jié)點(diǎn),為了方便我們定義一個新建結(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); //新建一個結(jié)點(diǎn) if(node == NULL){ return; } if(q-》head == NULL && q-》tail == NULL){ //首次插入一個結(jié)點(diǎn) q-》tail = node; q-》head = node; return; } q-》tail-》next = node; q-》tail = node; }

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

出隊(duì)

每次從隊(duì)列移除一個元素都需要釋放隊(duì)列結(jié)點(diǎn)內(nèi)存,為了方便我們定義一個是否結(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){ //只有一個結(jié)點(diǎn) q-》head = NULL; q-》tail = NULL; }else{ //不止一個結(jié)點(diǎn) q-》head = q-》head-》next; } node-》next = NULL; free_node(node); return data; }

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

獲取隊(duì)列長度

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ì)列長度只要從隊(duì)列頭結(jié)點(diǎn)不斷的遍歷隊(duì)列,判斷當(dāng)前結(jié)點(diǎn)是否已到隊(duì)列尾部,最后返回隊(duì)列長度。

銷毀隊(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)證

下面我們寫一個小程序驗(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ì)列長度: %d ”, queue_length(&queue)); printf(“取出隊(duì)列一個數(shù)據(jù):%d ”, dequeue(&queue)); printf(“取出隊(duì)列一個數(shù)據(jù):%d ”, dequeue(&queue)); printf(“隊(duì)列長度: %d ”, queue_length(&queue)); printf(“銷毀隊(duì)列 ”); queue_destroy(&queue); printf(“ ”); printf(“大小固定的隊(duì)列測試 ”); 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ì)列一個數(shù)據(jù):%d ”, dequeue_arr(&queue2)); printf(“取出隊(duì)列一個數(shù)據(jù):%d ”, dequeue_arr(&queue2)); if(queue_arr_is_full(&queue2)){ printf(“隊(duì)列已滿 ”); }else{ printf(“隊(duì)列未滿 ”); } printf(“隊(duì)列長度是:%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ì)列長度: 5 取出隊(duì)列一個數(shù)據(jù):1 取出隊(duì)列一個數(shù)據(jù):2 隊(duì)列長度: 3 銷毀隊(duì)列 大小固定的隊(duì)列測試 入隊(duì)順序 10 ,11 ,12 ,13 ,14 ,15 , 隊(duì)列已滿 取出隊(duì)列一個數(shù)據(jù):10 取出隊(duì)列一個數(shù)據(jù):11 隊(duì)列未滿 隊(duì)列長度是:4 銷毀隊(duì)列 隊(duì)列已空

輸出完全正確。

編輯:jq

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

    關(guān)注

    8

    文章

    7349

    瀏覽量

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

    關(guān)注

    3

    文章

    4422

    瀏覽量

    67870

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

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

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

掃碼添加小助手

加入工程師交流群

    評論

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

    RDMA設(shè)計(jì)25:隊(duì)列管理模塊發(fā)送模塊詳細(xì)設(shè)計(jì)分析

    發(fā)送隊(duì)列存儲為所有發(fā)送隊(duì)列共用的存儲空間,根據(jù)用戶環(huán)境和開發(fā)板環(huán)境不同可由 BRAM、URAM 或 LUTRAM 實(shí)現(xiàn)。發(fā)送隊(duì)列管理單元則負(fù)責(zé)管理這個存儲空間,并處理用戶指令和發(fā)送
    的頭像 發(fā)表于 01-25 16:27 ?5480次閱讀
    RDMA設(shè)計(jì)25:<b class='flag-5'>隊(duì)列</b>管理模塊<b class='flag-5'>之</b>發(fā)送模塊詳細(xì)設(shè)計(jì)分析

    RDMA設(shè)計(jì)27:隊(duì)列管理模塊設(shè)計(jì)完成模塊詳細(xì)分析

    。 (3)完成隊(duì)列 完成隊(duì)列的管理由完成條目解析單元和異常完成條目處理單元組成。完成條目解析單元中只設(shè)置了一個虛擬完成隊(duì)列,使用這樣的
    發(fā)表于 01-23 08:52

    RDMA設(shè)計(jì)26:隊(duì)列管理模塊設(shè)計(jì)接收隊(duì)列模塊詳細(xì)分析

    本文主要交流設(shè)計(jì)思路,在本博客已給出相關(guān)博文100多,希望對初學(xué)者有用。注意這里只是拋磚引玉,切莫認(rèn)為參考這就可以完成商用IP設(shè)計(jì)。 (2)接收隊(duì)列 接收隊(duì)列由一個接收隊(duì)列管理單元組
    發(fā)表于 01-22 09:03

    RDMA設(shè)計(jì)24:隊(duì)列管理模塊設(shè)計(jì)

    隊(duì)列管理模塊采用管理與存儲分離的結(jié)構(gòu)進(jìn)行設(shè)計(jì),由發(fā)送隊(duì)列存儲、發(fā)送隊(duì)列管理、接收隊(duì)列管理、完成條目解析
    的頭像 發(fā)表于 01-20 11:45 ?1581次閱讀
    RDMA設(shè)計(jì)24:<b class='flag-5'>隊(duì)列</b>管理模塊設(shè)計(jì)

    RDMA設(shè)計(jì)18:隊(duì)列管理模塊設(shè)計(jì)3

    本文主要交流設(shè)計(jì)思路,在本博客已給出相關(guān)博文140多,希望對初學(xué)者有用。注意這里只是拋磚引玉,切莫認(rèn)為參考這就可以完成商用IP設(shè)計(jì)。 (3)完成隊(duì)列 完成隊(duì)列的管理由完成條目解析單元
    發(fā)表于 01-05 09:04

    C語言的循環(huán)隊(duì)列

    data; } return -1; // Buffer is empty } 循環(huán)隊(duì)列是一種高效的數(shù)據(jù)結(jié)構(gòu),適用于緩沖區(qū)和數(shù)據(jù)流應(yīng)用,例如串口通信接收緩沖。
    發(fā)表于 12-12 08:28

    NVMe高速傳輸擺脫XDMA設(shè)計(jì)53:如何測試隊(duì)列管理功能

    管理功能, 對隊(duì)列的創(chuàng)建、 刪除功能和隊(duì)列管理邊界進(jìn)行了測試。 創(chuàng)建隊(duì)列測試打印信息如圖1 所示, 在初始化完成后, 創(chuàng)建 I/O 完成隊(duì)列和提交隊(duì)
    發(fā)表于 12-09 08:21

    優(yōu)先級隊(duì)列介紹

    隊(duì)列(Queue)的知識點(diǎn):「概念」:隊(duì)列是一種先進(jìn)先出(FIFO)的數(shù)據(jù)結(jié)構(gòu),類似于排隊(duì)的概念?!富静僮鳌梗篹nqueue(item): 將元素添加到隊(duì)列的末尾。dequeue()
    發(fā)表于 11-26 07:56

    基于環(huán)形隊(duì)列的UART收發(fā)回顯實(shí)驗(yàn)

    問題。在本實(shí)驗(yàn)中,我們使用環(huán)形隊(duì)列實(shí)現(xiàn)實(shí)驗(yàn)1的串口收發(fā)回顯,將串口接收到的數(shù)據(jù)暫存在隊(duì)列中,待完成一次接收后再將
    的頭像 發(fā)表于 10-27 13:51 ?2177次閱讀
    基于<b class='flag-5'>環(huán)形</b><b class='flag-5'>隊(duì)列</b>的UART收發(fā)回顯實(shí)驗(yàn)

    NVMe高速傳輸擺脫XDMA設(shè)計(jì)39:隊(duì)列管理功能驗(yàn)證與分析3

    本文主要交流NVMe設(shè)計(jì)思路,在本博客已給出相關(guān)博文九十多,希望對初學(xué)者有用。注意這里只是拋磚引玉,切莫認(rèn)為參考這就可以完成商用IP設(shè)計(jì)。 測試步驟 4 關(guān)鍵信號波形如圖1 所示。 創(chuàng)建深度
    發(fā)表于 10-20 16:01

    NVMe高速傳輸擺脫XDMA設(shè)計(jì)38:隊(duì)列管理功能驗(yàn)證與分析2

    波形如圖1 所示。 創(chuàng)建深度為 1024 的 I/O 提交隊(duì)列, 由于支持的最大隊(duì)列深度為 1023, 所以創(chuàng)建返回狀態(tài) cr_status 值為 4, 表示創(chuàng)建
    發(fā)表于 10-15 08:14

    NVMe高速傳輸擺脫XDMA設(shè)計(jì)37:隊(duì)列管理功能驗(yàn)證與分析1

    本文主要交流設(shè)計(jì)思路,在本博客已給出相關(guān)博文九十多,希望對初學(xué)者有用。注意這里只是拋磚引玉,切莫認(rèn)為參考這就可以完成商用IP設(shè)計(jì)。若有產(chǎn)品或項(xiàng)目需求,請看B站視頻后聯(lián)系 隊(duì)列管理功能主要包含創(chuàng)建
    發(fā)表于 10-13 11:17

    NVMe IP高速傳輸卻不依賴XDMA設(shè)計(jì)九:隊(duì)列管理模塊(上)

    這是采用PCIe設(shè)計(jì)NVMe,并非調(diào)用XDMA方式,后者在PCIe4.0時不大方便,故團(tuán)隊(duì)直接采用PCIe設(shè)計(jì),結(jié)合UVM驗(yàn)證加快設(shè)計(jì)速度。 隊(duì)列管理模塊采用隊(duì)列的存儲與控制分離的設(shè)計(jì)結(jié)構(gòu)。
    的頭像 發(fā)表于 08-04 09:53 ?870次閱讀
    NVMe IP高速傳輸卻不依賴XDMA設(shè)計(jì)<b class='flag-5'>之</b>九:<b class='flag-5'>隊(duì)列</b>管理模塊(上)

    NVMe高速傳輸擺脫XDMA設(shè)計(jì)十:隊(duì)列管理模塊設(shè)計(jì)(下)

    ,通過修改表單的信息便可以修改隊(duì)列數(shù)量和深度。在實(shí)際應(yīng)用中,當(dāng)出現(xiàn)大量隨機(jī)數(shù)據(jù)讀寫請求時,可以通過修改表單增加隊(duì)列數(shù)量和深度,增強(qiáng)隨機(jī)讀寫性
    發(fā)表于 07-30 16:27

    NVMe高速傳輸擺脫XDMA設(shè)計(jì)九:隊(duì)列管理模塊設(shè)計(jì)(上)

    設(shè)計(jì),結(jié)合UVM驗(yàn)證加快設(shè)計(jì)速度。隊(duì)列管理模塊采用隊(duì)列的存儲與控制分離的設(shè)計(jì)結(jié)構(gòu),如圖1所示為隊(duì)列管理模塊的結(jié)構(gòu)框圖。 圖1
    發(fā)表于 07-27 17:41
    滨海县| 西畴县| 婺源县| 沁源县| 广德县| 余江县| 鹿邑县| 平潭县| 东港市| 吉木乃县| 兴宁市| 库尔勒市| 崇义县| 自贡市| 新郑市| 阿坝县| 平顶山市| 建水县| 上虞市| 七台河市| 滕州市| 嘉禾县| 广丰县| 连江县| 麻城市| 朝阳区| 巩义市| 邯郸县| 富宁县| 砚山县| 绩溪县| 都匀市| 颍上县| 勃利县| 吉隆县| 镇远县| 江都市| 永寿县| 长海县| 会宁县| 二手房|