那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

一種數組環形隊列的數據結構

技術讓夢想更偉大 ? 來源:CSDN-閼男秀 ? 2023-04-26 09:17 ? 次閱讀

概述

一種更好的計算隊尾指針的方法。

隊尾指針新算法

一個新的計算隊尾指針的公式:

模擬環形隊列的線性表長度是N,隊頭指針為head,隊尾指針為tail,則每增加一條記錄,就可以用一下方法計算新的隊尾指針: tail = (tail + 1) % N

780c9d90-e3b6-11ed-ab56-dac502259ad0.jpg

環形隊列示意圖

思考

但是,我在移植到8266的代碼時,發現有點問題。

第一,head和tail應該是存儲該數組的下標而不是一個指向該數組元素的指針。如果tail是指針,那么 tail本質上是一個內存地址,*tail是指向該數組的某一元素。那么這算式tail = (tail + 1) % N其實是對某數組元素的內存地址+1,然后在用N求余。 所以head和tail應該是保存該數組的下標,而不是指向該數組元素的指針。

第二,由于原先的代碼,其隊尾指針總是指向最后一個入隊元素的下一個元素,而《算》給出的隊列,隊尾指針總是指向最后一個入隊的元素。如上圖,一個N=12的環形隊列,原先的代碼tail是指向第8個,《算》是指向第7個,由于我是在8266的示例代碼上修改的,所以《算》給出的隊尾指針算法需要調整一下:

//元素入隊之后
tail++;//tail指向最后一個入隊的下一個元素
tail=tail%N;//重新計算tail的數值123

新的數據結構

那么我就開始定義新的數據結構了,原先的數據結構是這樣的

typedefstruct{
uint8_t*p_o;//指向原點的指針,用來數組首地址
uint8_t*volatilep_r;//讀取指針,相當于head
uint8_t*volatilep_w;//寫入指針,相到于tail
volatileint32_tfill_cnt;//隊列計數
int32_tsize;//緩沖區的大小
}RINGBUF;

新的數據結構:

typedefstruct{
char*buf;//指向隊列數組的指針
unsignedintlength;//數組長度
unsignedinthead;//隊頭,存儲數組下標
unsignedinttail;//隊尾,存儲數組下標
intfill_cnt;//隊列計數
}RINGBUF;

判斷是否空隊列

一開始,本來想用if(head==tail)來判斷隊列是否為空的,但是由于tail保存的是入隊元素的下一個數組下標,當隊列填滿的時候,tail的下標正好等于head,所以不能通過if(head==tail)來判斷隊列是否為空,

完整代碼

下面是完整的數組環形隊列代碼,運行環境是VS2015,主函數里進行了簡單的測試:

// RingBuf.cpp :定義控制臺應用程序的入口點。
//

#include"stdafx.h"

typedefstruct{
char*buf;//指向隊列數組的指針
unsignedintlength;//長度
unsignedinthead;//隊頭
unsignedinttail;//隊尾
intfill_cnt;//隊列計數
}RINGBUF;

intRINGBUF_Init(RINGBUF*r,chararray[],size_tlen)
{
if(len<2?||?array==NULL){
????????return?false;
????}

????r->buf=array;
r->length=len;
r->fill_cnt=0;
r->head=r->tail=0;
returntrue;
}

intRINGBUF_Put(RINGBUF*r,chardata)
{
//當tail+1等于head時,說明隊列已滿
if(r->fill_cnt>=r->length){
printf("BUFFULL!
");
returnfalse;//如果緩沖區滿了,則返回錯誤
}

r->buf[r->tail]=data;
r->tail++;
r->fill_cnt++;
//計算tail是否超出數組范圍,如果超出則自動切換到0
r->tail=r->tail%r->length;
returntrue;
}

intRINGBUF_Get(RINGBUF*r,char*c,unsignedintlength)
{
//當tail等于head時,說明隊列空
if(r->fill_cnt<=0)?{
????????printf("BUF?EMPTY!
");
????????return?false;
????}

????//最多只能讀取r->length長度數據
if(length>r->length){
length=r->length;
}

inti;
for(i=0;ifill_cnt--;
*c=r->buf[r->head++];//返回數據給*c
*c++;
//計算head自加后的下標是否超出數組范圍,如果超出則自動切換到0
r->head=r->head%r->length;
}
returntrue;
}



#defineBUF_LEN5
RINGBUFBUFF;
charbuf[BUF_LEN];

intmain()
{
RINGBUF_Init(&BUFF,buf,sizeof(buf));

printf("1、逐個讀取數據測試
");
intlength=5;
for(inti=0;i

控制臺打印信息如下:

1、逐個讀取數據測試
每次讀取1個字節:buf pop : 0
每次讀取1個字節:buf pop : 1
每次讀取1個字節:buf pop : 2
每次讀取1個字節:buf pop : 3
每次讀取1個字節:buf pop : 4

2、一次性讀取測試
一次性讀取5個字節:buf pop : 12345

3、放入超過緩沖區長度(BUF_LEN+1)數據測試:
BUF FULL!
一次性讀取(BUF_LEN+1)個字節測試:buf pop : 12345

4、讀取空緩沖區測試:
BUF EMPTY!
請按任意鍵繼續…

后話

由于存在幾種隊尾指向元素的方式,以上代碼是還可以在修改優化一下的。

《算》的代碼是不需要考慮隊列是否滿了,他只需要直接覆蓋舊的元素即可,我的需求是需要判斷隊列是否填滿,以免舊的元素被覆蓋。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 算法
    +關注

    關注

    23

    文章

    4630

    瀏覽量

    93352
  • 指針
    +關注

    關注

    1

    文章

    481

    瀏覽量

    70608
  • 代碼
    +關注

    關注

    30

    文章

    4825

    瀏覽量

    69043
  • 數據結構
    +關注

    關注

    3

    文章

    573

    瀏覽量

    40230
  • 數組
    +關注

    關注

    1

    文章

    417

    瀏覽量

    26028

原文標題:一種數組環形隊列的數據結構

文章出處:【微信號:技術讓夢想更偉大,微信公眾號:技術讓夢想更偉大】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    嵌入式常用數據結構------隊列操作簡介

    嵌入式常用數據結構------隊列操作簡介隊列是嵌入式軟件中常用的一種數據結構。什么是隊列呢?在生活中,我們都知道,買東西時要排隊,比如最近
    發表于 06-17 17:30

    收藏 | 程序員面試,你必須知道的8大數據結構

    數據結構首先列出些最常見的數據結構,我們將逐說明:數組隊列鏈表樹圖字典樹(這是
    發表于 09-30 09:35

    常見的數據結構

    胡亂的,這就要求我們選擇一種好的方式來存儲數據,而這也是數據結構的核心內容。數據存儲直以來大家面對的
    發表于 05-10 07:58

    數據結構隊列順序及其構造

    數據結構隊列順序隊列構造順序隊列順序隊列的初始化判斷隊列是否滿判斷
    發表于 12-17 06:11

    實現隊列環形緩沖的方法

    串口隊列環形緩沖區隊列串口環形緩沖的好處代碼實現隊列??要實現隊列
    發表于 02-21 07:11

    環形隊列的相關資料分享

    的小伙伴,對隊列肯定不會陌生,隊列相對來說是比較簡單的數據結構,典型特點是FIFO,即First in First out,先進先出,就像我們日常排隊買票樣,先到的人先買票,先從購票
    發表于 02-23 06:10

    數據結構的簡介和線性表及棧隊列數組的詳細說明

    兩項基本任務:數據表示,數據處理 軟件系統生存期:軟件計劃,需求分析,軟件設計,軟件編碼,軟件測試,軟件維護 由一種邏輯結構組基本運
    發表于 01-06 08:00 ?0次下載

    深度解析數據結構與算法篇之隊列環形隊列的實現

    01 — 隊列簡介 隊列先進先出的數據結構,有個元素進入隊列稱為入對(enqueue),刪除元素稱為出隊(dequeue),
    的頭像 發表于 06-18 10:07 ?2001次閱讀

    STM32串口環形緩沖--使用隊列實現(開放源碼)

    串口隊列環形緩沖區隊列串口環形緩沖的好處代碼實現隊列??要實現隊列
    發表于 12-24 19:04 ?28次下載
    STM32串口<b class='flag-5'>環形</b>緩沖--使用<b class='flag-5'>隊列</b>實現(開放源碼)

    SystemVerilog中可以嵌套的數據結構

    SystemVerilog中除了數組隊列和關聯數組數據結構,這些數據結構還可以嵌套。
    的頭像 發表于 11-03 09:59 ?1666次閱讀

    嵌入式環形隊列和消息隊列的實現

    嵌入式環形隊列和消息隊列是實現數據緩存和通信的常見數據結構,廣泛應用于嵌入式系統中的通信協議和領域。
    的頭像 發表于 04-14 11:52 ?1623次閱讀

    數據結構解決滑動窗口問題

    前文用 [單調棧解決三道算法問題]介紹了單調棧這種特殊數據結構,本文寫個類似的數據結構「單調隊列」。 也許這種數據結構的名字你沒聽過,其
    的頭像 發表于 04-19 10:50 ?702次閱讀
    <b class='flag-5'>數據結構</b>解決滑動窗口問題

    redis的五種數據類型底層數據結構

    Redis是一種內存數據存儲系統,支持多種數據結構。這些數據結構不僅可以滿足常見的存儲需求,還能夠通過其底層數據結構提供高效的操作和查詢。以
    的頭像 發表于 11-16 11:18 ?745次閱讀

    redis數據結構的底層實現

    Redis是一種內存鍵值數據庫,常用于緩存、消息隊列、實時數據分析等場景。它的高性能得益于其精心設計的數據結構和底層實現。本文將詳細介紹Re
    的頭像 發表于 12-05 10:14 ?664次閱讀

    嵌入式環形隊列與消息隊列的實現原理

    嵌入式環形隊列,也稱為環形緩沖區或循環隊列,是一種先進先出(FIFO)的數據結構,用于在固定大小
    的頭像 發表于 09-02 15:29 ?658次閱讀
    东莞百家乐官网的玩法技巧和规则| 至尊百家乐官网娱乐场开户注册| 百家乐官网筹码500| 网络百家乐官网可靠吗| 百家乐官网为什么庄5| 澳门百家乐官网技巧经| 百家乐官网八卦投注法| 现金百家乐官网攻略| 榆次百家乐官网的玩法技巧和规则 | 百家乐官网作弊演示| 顶级赌场下载| 网上百家乐赌| 百家乐挂机软件| 永利高百家乐开户| 大世界百家乐官网娱乐| 百家乐官网必胜法hk| 十六蒲娱乐城| 大发888提款速度快吗| 百家乐桌套装| 尊龙百家乐娱乐场| 百家乐现场新全讯网| 金钱豹百家乐官网的玩法技巧和规则| 澳门百家乐官网群策略| 葡京百家乐官网技巧| 足球投注技巧| 德州扑克 比赛| 大发888娱乐城刮刮乐| 悍马百家乐的玩法技巧和规则| 24山家坐向| 大中华百家乐官网的玩法技巧和规则| 百家乐官网最大的赌局 | 百家乐官网怎样下注| 百家乐官网技术辅助软件| 川宜百家乐官网破解版| 山东省| 鸿运娱乐城| 大发888娱乐场东南网| 大发888投注大发娱乐| 百家乐庄闲桌| 恒利百家乐的玩法技巧和规则| 网络百家乐公式打法|