環形隊列

在網上看到一篇比較好的介紹隊列的文章,地址為:http://www.cnblogs.com/kubixuesheng/p/4104802.html

特此感謝原創作者,以下均為摘抄。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1、順序隊列

?限制僅在表頭刪除和表尾插入的順序表,利用一組地址連續的存儲單元依次存放隊列中的數據元素。因為隊頭和隊尾的位置是變化的,所以也要設頭、尾指針。 ?

?

初始化時的頭尾指針,初始值均應置為 0。?入隊尾指針增 1 ,出隊頭指針增 1 。頭尾指針相等時隊列為空,在非空隊列里,頭指針始終指向隊頭元素,尾指針始終指向隊尾元素的下一位置。

初始為空隊列,那么頭尾指針相等。

入隊,那么尾指針加1,頭指針不變。先進先出,J1先進隊,則 rear+1,尾指針始終指向隊尾元素的下一位!如,J2進隊,rear 繼續+1,J3進隊,尾指針繼續加1,如圖

?

出隊,則尾指針不變,頭指針加1,注意這里都是加1,先進先出原則,J1先刪除,front+1,指向了 J2,J2刪除,front+1指向了 J3,如圖

?

最后,J3刪除,則頭指針再次和尾指針相等,說明隊列空了。如圖

在順序隊列中,當尾指針已經指向了隊列的最后一個位置的下一位置時,若再有元素入隊,就會發生“溢出”。如圖位置,再次入隊,就會溢出。

?

2、循環隊列的誕生

順序隊列的 “假溢出” 問題:隊列的存儲空間未滿,卻發生了溢出。很好理解,比如 rear 現在雖然指向了最后一個位置的下一位置,但是之前隊頭也刪除了一些元素,那么隊頭指針經歷若干次的 +1 之后,遺留下了很多空位置,但是順序隊列還在傻乎乎的以為再有元素入隊,就溢出呢!肯定不合理。故循環隊列誕生!

解決“假溢出”的問題有兩種可行的方法:

(1)、平移元素:把元素平移到隊列的首部。效率低。否決了。

(2)、將新元素插入到第一個位置上,構成循環隊列,入隊和出隊仍按“先進先出”的原則進行。操作效率高、空間利用率高。

? ? ??

雖然使用循環隊列,解決了假溢出問題,但是又有新問題發生——判空的問題,因為僅憑 front = rear 不能判定循環隊列是空還是滿。比如如圖:

這是空循環隊列的樣子

這是滿循環隊列的樣子

解決辦法:

(1)、另設一個布爾變量以區別隊列的空和滿;

(2)、少用一個元素的空間,約定入隊前測試尾指針在循環下加 1 后是否等于頭指針,若相等則認為隊滿;(最常用)

(3)、使用一個計數器記錄隊列中元素的總數。

對于第2個方案,必須犧牲一個元素的空間,那么入隊的時候需要測試,循環意義下的加 1 操作可以描述為:

1     if (rear + 1 = MAXQSIZE)
2 
3            rear = 0;
4 
5      else
6 
7           rear ++; 

?

利用模運算可簡化為:

?

1 rear = (rear + 1)% MAXQSIZE  

基本操作

復制代碼
 1 #ifndef ___queue_Header_h2 #define ___queue_Header_h3 #include <stdio.h>4 #include <stdlib.h>5 #define MAX_SIZE 56 7 typedef struct{8     int *base;9     int rear;//如果隊列不空,指向隊尾元素的下一個位置
10     int front;//初始的時候指向表頭
11 } CirularQueue;
12 
13 //初始化
14 void initQueue(CirularQueue *queue)
15 {
16     queue->base = (int *)malloc(MAX_SIZE*sizeof(int));
17     
18     if (NULL == queue->base) {
19         exit(0);
20     }
21     
22     queue->front = queue->rear = 0;
23 }
復制代碼

求長度

復制代碼
//求長度
int getLength(CirularQueue queue)
{//這樣把所以的情況都考慮到了return (queue.rear - queue.front + MAX_SIZE) % MAX_SIZE;
}
復制代碼

第一種情況,長度的求法

第二種情況,長度的求法,利用模運算,兩個情況合二為一!

復制代碼
//入隊,先判滿
void insertQueue(CirularQueue *queue, int e)
{if ((queue->rear + 1) % MAX_SIZE == queue->front) {puts("循環隊列是滿的!");}else{queue->base[queue->rear] = e;queue->rear = (queue->rear + 1) % MAX_SIZE;}
}
復制代碼

如下時為滿,損失一個空間,不存儲元素。方便判滿

1 //出隊2 void deleteQueue(CirularQueue *queue)3 {4     if (queue->front == queue->rear) {5         puts("隊列是空的!");6     }7     else8     {9         queue->front = (queue->front + 1) % MAX_SIZE;
10     }
11 }
12 
13 //遍歷
14 void traversal(CirularQueue queue)
15 {
16     int q = queue.front;
17     
18     for (int i = 0; i < getLength(queue); i++) {
19         printf("循環隊列的第%d個元素為%d\n", i + 1, queue.base[q]);
20         q ++; 
21 }
22 }
23
24 #endif

為了尊重原創我將原作者的代碼貼上來了,但對最后一個遍歷持保留意見,我覺得后面直接q++不會有問題嗎?

我個人覺得應該改成:

//遍歷
void traversal(CirularQueue queue)
{int q = queue.front;for (int i = 0; i < getLength(queue); i++) {printf("循環隊列的第%d個元素為%d\n", i + 1, queue.base[q]);q = (q + 1)%MAX_SIZE; } 
}  

  

?

轉載于:https://www.cnblogs.com/kent-hu/p/7580960.html

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

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

相關文章

HTTP1.0、HTTP1.1 、SPDY、HTTP2.0之演變過程和優化

一、協議的演變過程和時間 HTTP1.0(1996年) -> HTTP1.1(1999年) -> SPDY(2012年google提出了SPDY的方案) -> HTTP2.0(2013年8月進行首次合作共事性測試) 二、影響一個HTTP網絡請求的因素 主要有兩個:帶寬和延遲 1)帶寬:網絡基礎建設已經使得帶寬得到極大的提升…

OK335xS GPMC nand device register hacking

/********************************************************************************** OK335xS GPMC nand device register hacking* 說明&#xff1a;* 由于最近遇到No NAND device found這個內核錯誤&#xff0c;在網絡上也沒找到很好的* 解決辦法&am…

Blazor University (19)使用 RenderFragments 模板化組件 —— 數據傳遞

原文鏈接&#xff1a;https://blazor-university.com/templating-components-with-renderfragements/passing-data-to-a-renderfragement/將數據傳遞給 RenderFragment源代碼[1]到目前為止&#xff0c;我們使用了僅包含子標記的 RenderFragments&#xff0c;然后在渲染組件時按…

一頭扎進Node(三) - File System

file.open:異步模式打開文件 fs.open(path, flags[, mode], callback) 案例代碼如下&#xff1a; var fs require(fs);/*** 參數說明&#xff1a;* 1.path&#xff1a;要打開的文件的文件路徑* 2.flags&#xff1a;打開文件的方式 讀/寫* r&#xff1a;只讀方式打開文件…

《零基礎看得懂的C語言入門教程 》——(十二)原來結構體是這么回事

一、學習目標 了解C語言的結構體的使用方法了解C語言結構體的結構的賦值了解多種C語言結構體變量的賦值方法和取值方法 目錄 C語言真的很難嗎&#xff1f;那是你沒看這張圖&#xff0c;化整為零輕松學習C語言。 第一篇&#xff1a;&#xff08;一&#xff09;脫離學習誤區 第…

【學生選課系統經典】C#與SQLSERVER連接:Windows應用工程案例

實驗任務描述 1 用C#訪問SQLSERVER數據庫(兩種安全模式); 2 用C#完成數據庫指定表上的數據顯示; 3 用C#完成數據庫指定表上的數據插入、刪除和更新; 4 用C#完成數據庫用戶驗證。 注意,由于C#語言的強大功能,下面的代碼適用于SQLSERVER2000、也適合于SQLSERVER2005。區別僅…

Java精選筆記_JDBC

JDBC概述 什么是JDBC JDBC全稱是Java數據庫連接&#xff08;Java Database Connectivity&#xff09;&#xff0c;應用程序可通過這套API連接到關系數據庫&#xff0c;并使用SQL語句來完成對數據庫中數據的查詢、更新和刪除等操作。是一套用于執行SQL語句的Java API。Java的數據…

mysql關系數據庫引擎_MySQL數據庫引擎詳解

作為Java程序員&#xff0c;MySQL數據庫大家平時應該都沒少使用吧&#xff0c;對MySQL數據庫的引擎應該也有所了解&#xff0c;這篇文章就讓我詳細的說說MySQL數據庫的Innodb和MyIASM兩種引擎以及其索引結構。也來鞏固一下自己對這塊知識的掌握。Innodb引擎Innodb引擎提供了對數…

Java之synchronized的JVM底層實現原理精簡理解

1 synchronized的JVM底層原理實現的精簡理解 Java 虛擬機中的synchronized基于進入和退出Monitor對象&#xff08;也稱為管程或監視器鎖&#xff09;實現&#xff0c; 無論是顯式同步(synchronized作用在同步代碼塊&#xff0c;有明確的 monitorenter 和 monitorexit 指令) 還是…

三分鐘掌握Actor和CSP模型

點擊上方藍字進行關注前文傳送門&#xff1a;《三分鐘掌握共享內存模型和 Actor模型》&#xff0c; 一直想比較Actor模型與golang的CSP模型&#xff0c;經過一段時間的實戰記錄了本文。Actor vs CSP模型? 傳統多線程的的共享內存&#xff08;ShareMemory&#xff09;模型使用l…

DateTimeToUnix/UnixToDateTime 對接時間轉換

問題&#xff0c;通過毫秒數來解析出時間&#xff1a;&#xff08;很多對接的時候經常需要用到&#xff09; <?php $MyJson {"jingdong_vas_subscribe_get_responce":{"code":"0","item_code":"FW_GOODS-2236-1","…

【學生選課系統經典】VB與SQLSERVER連接:Windows應用工程案例

實驗任務描述 1 用VB6訪問SQLSERVER數據庫(兩種安全模式); 2 用VB6完成數據庫指定表上的數據顯示; 3 用VB6完成數據庫指定表上的數據插入、刪除和更新; 4 用VB6完成SQLSERVER2008數據庫用戶驗證。 一、數據庫系統 該實驗中,所要求的數據庫名稱為SCHOOL,總共涉及以下表:

丟失api-ms-win-crt-runtime-l1-1-0.dll

運行Cmder的時候提示&#xff1a;丟失api-ms-win-crt-runtime-l1-1-0.dll在網上找了一些方法&#xff0c;基本解決方法都是裝VC2015的運行時&#xff0c;但是我安裝的時候出錯&#xff0c;大家可以先試試。接著我就去解決安裝出錯這問題沒&#xff0c;折騰了半天也沒成功。后來…

《假如編程是魔法之零基礎看得懂的Python入門教程 》——(二)魔法實習生第一步了解魔杖的使用

學習目標 了解什么是開發環境了解python語言的環境安裝了解python語言編程的編輯器工具 目錄 第一篇&#xff1a;《假如編程是魔法之零基礎看得懂的Python入門教程 》——&#xff08;一&#xff09;既然你選擇了這系列教程那么我就要讓你聽得懂 第三篇&#xff1a;《假如編…

Java之synchronized可重入性的理解

1 synchronized可重入性的理解 當一個線程試圖操作一個由其他線程持有的對象鎖的臨界資源時&#xff0c;將會處于阻塞狀態&#xff0c;但當一個線程再次請求自己持有對象鎖的臨界資源時&#xff0c;如果當前鎖是重入性&#xff0c;會請求將會成功&#xff0c;如果當前鎖不是可…

onmouseover-onmouseout

<input type"checkbox" value"autoLogin" οnmοuseοver"block()" οnmοuseοut"none()">兩周內自動登錄 <div id"div1">為了您的信息安全請不要在網吧或公共電腦勾選此項</div> <script> functi…

mysql5.7 only_full_group_by_Mysql5.7及以上版本 ONLY_FULL_GROUP_BY報錯的解決方法

近期在開發過程中&#xff0c;因為項目開發環境連接的mysql數據庫是阿里云的數據庫&#xff0c;而阿里云的數據庫版本是5.6的。而測試環境的mysql是自己安裝的5.7。因此在開發過程中有小伙伴不注意寫了有關group by的sql語句。在開發環境中運行是正常的&#xff0c;而到了測試環…

一款高速的NET版的離線免費OCR

PaddleOCR.Onnx一款基于Paddle的OCR&#xff0c;項目使用ONNX模型&#xff0c;速度更快。本項目同時支持X64和X86的CPU上使用。本項目是一個基于PaddleOCR的C代碼修改并封裝的.NET的工具類庫。包含文本識別、文本檢測、基于文本檢測結果的統計分析的表格識別功能&#xff0c;同…

spring 注解簡單使用

一、通用注解 1、項目結構&#xff1a; 2、新建Person類&#xff0c;注解Component未指明id&#xff0c;則后期使用spring獲取實例對象時使用默認id"person"方式獲取或使用類方式獲取 package hjp.spring.annotation.commen;import org.springframework.stereotype.C…

selenium+python筆記3

#!/usr/bin/env python # -*- coding: utf-8 -*- """ desc:學習unittest的用法 注意setUp/setUpClass&#xff0c;tearDown/tearDownClass的區別 ① setUp():每個測試函數運行前運行 ② tearDown():每個測試函數運行完后執行 ③ setUpClass():必須使用classmeth…