① 循環隊列中入隊與出隊演算法
如果循環隊列每個元素有兩個指針,一個指向其前面的元素pPre,一個指向後面的元素pNext,出對和入隊就是修改一下指針啊。
比如指向要出隊的元素的指針是 pDel,那麼出隊就應該是:
pDel->pPre->pNext = pDel->pNext;
pDel->pNext->pPre = pDel->pPre;
如果循環隊列每個元素只有一個指向其後元素的指針pNext,那麼需要遍歷整個隊列,找到要出隊元素的前一個元素,然後就和上面的演算法差不多了。
如果經常要進行出隊操作,在設計數據結構的時候還是建議每個元素使用兩個指針。
② 求循環隊列的元素個數演算法,已知front 和 rear,還有容量數,怎麼求隊列中的循環元素個數
如果是用數組實現的 用隊尾減隊頭再模數組長度;如果是鏈表 就要有個計數變數了。
front為對頭指針,rear為對尾指針,n為隊列最大元素個數。隊列元素個數=(rear-front+1+n)%n %是求余數。
循環隊列的元素個數計算公式:
如果rear<front結果是rear-front+maxsize;
如果rear>front結果是rear-front;
為了用一個表達式同時表達兩者,用(rear-front+maxsize)%maxsize;
假設maxsize=10;
rear=1 front=9,那麼結果是2;
rear=9 front=1,那麼結果是8。
(2)循環隊列的演算法描述擴展閱讀
循環隊列中,由於入隊時尾指針向前追趕頭指針;出隊時頭指針向前追趕尾指針,造成隊空和隊滿時頭尾指針均相等。因此,無法通過條件front==rear來判別隊列是"空"還是"滿"。
解決這個問題的方法至少有兩種:
① 另設一布爾變數以區別隊列的空和滿;
②另一種方式就是數據結構常用的: 隊滿時:(rear+1)%n==front,n為隊列長度(所用數組大小),由於rear,front均為所用空間的指針,循環只是邏輯上的循環,所以需要求余運算。
隊已滿,但是rear(5)+1=6!=front(0),對空間長度求余,作用就在此6%6=0=front(0)。
③ 對於循環隊列,試寫出求隊列長度的演算法.
include<iostream>
using namespace std;
#define MAX_QSIZE 5
typedef int ElemType;
typedef struct SqQueue //循環隊列結構體定義
{
ElemType *base;
int front;
int rear;};
void InitQueue(SqQueue *&Q)
{
Q=(SqQueue *)malloc(MAX_QSIZE*sizeof(SqQueue));
Q->rear=Q->front;
}
int EmptyQueue(SqQueue *Q)
{
if(Q->rear==Q->front)
return 0;
else return 1;
}
void DestroyQueue(SqQueue *Q)
{
if(Q->base) free(Q->base);
Q->base=NULL;
Q->front=Q->rear;
}
void ClearQueue(SqQueue *Q)
{
Q->rear=Q->front;
}
int LenghtQueue(SqQueue *Q) //求隊列長度函數
{
return (Q->front-Q->rear+MAX_QSIZE)%MAX_QSIZE;
}
int EnQueue(SqQueue *&Q,ElemType &e) //入隊操作
{
if((Q->rear+1)%MAX_QSIZE==Q->front)
return 0;
else Q->base[Q->rear]=e;
Q->rear=(Q->rear+1)%MAX_QSIZE;
return 1;
}
int DeQueue(SqQueue *&Q,ElemType &e) //出隊操作
{
if(Q->rear==Q->front)
return 0;
else e=Q->base[Q->front];
cout<<e<<endl;
Q->front=(Q->front+1)%MAX_QSIZE;
return 1;
}
int main()
{
SqQueue *Q; InitQueue(Q);
int a[9]={0,1,2,3,4,5,6,7,8};
for(int i=0;i<9;i++)
{
EnQueue(Q,a[i]);
}
cout<<LengthQueue(Q)<<endl; return 0;
for(i=0;i<9;i++)
{
DeQueue(Q,a[i]);
}
}
④ 循環隊列FIFO原理及C實現
循環隊列概念與基本原理
循環隊列,本質上是對順序隊列進行尾部連通形成閉合環形邏輯鏈,以此提升空間利用效率。當頭指針遇到尾指針時,循環繼續從頭部開始,如同鏈條一般環環相扣。
構建一個循環隊列結構體包含三個核心組件:指針front指頭元素索引、指針指向元素的結構體struct type *fifo以及尾元素索引tail。同時,設定隊列容量capacity。
實例展示
初始化循環隊列流程:分配連續內存存儲元素。
循環隊列銷毀與空/滿狀態判定:隊列空狀態在初始化時front置-1;出隊後,front自增,若front回到tail說明隊空,重新設定front和tail皆為-1。若front到達尾或當front回到0且tail為capacity-1時,則隊列為滿。
循環隊列操作流程
入隊操作:尾元素索引後移,即自增tail值。隊空時,首次元素入隊,front、tail均指向首元素。其他情況入隊時,僅需自增tail。
出隊操作:移除頭元素,即遞增front值。front與tail相遇時,視為隊空,需將front、tail重新置為-1。其他情況下,直接丟棄front元素,後移front。
總元素數量與有效元素計數
通過尾索引減去頭索引可得出總元素數,考慮到循環特性,實際可能為tail與front之差模隊列容量。有效元素數量即為上述差值。
循環隊列遍歷與獲取元素
循環隊列遍歷需遵循環形結構,獲取隊尾元素和隊首元素需分別處理,具體演算法需根據隊列實現進行調整。
實際應用與驗證
設計一套簡單測試流程,驗證循環隊列實現邏輯與性能。這包括循環隊列初始化、數據插入、數據檢索和清理等操作,以及通過比較預期結果和實際結果驗證正確性。
⑤ 數據結構循環隊列問題
網路版本是對的。你沒理解「隊列非空時front和rear分別指向隊頭元素和隊尾元索」,根據這句話當隊列只有一個元素時,front==rear;當隊為空時,front==(rear+1)%n;進隊的操作為:rear = (rear + 1) % n ;Queue[rear] = elem ;元素正好在下標為0的位置,此時front==rear==0。「隊列非空時front和rear分別指向隊頭元素和隊尾元索」意思就是front和rear都是「實指」,而你的理解中front是「虛指」,不同教材採用的方法不一樣,一般題目中會說明
⑥ 數據結構—隊列
隊列 (queue)是一種先進先出的線性表。它只允許在表的一端進行插入,在另一端進行刪除,這如同我們日常生活中的排列是一致的,最早入隊的元素最早離開。
隊尾 (rear)是隊列中允許插入的一端, 隊頭 (front)是隊列中允許刪除的一端。
隊列如同棧一樣,也同樣有兩種存儲表示,分別是順序表示和鏈式表示。
和順序棧類似,在隊列的順序存儲結構中,除了用一組地址連續的存儲單元依次存放從隊列頭到對列尾的元素之外,需要設置兩個指針front和rear分別指示隊列頭元素和尾元素的位置。
隊列的順序存儲結構表示如下:
為方便C語言描述起見,約定:初始化建空隊列時,front=rear=0,每當插入新元素至隊尾時,「尾指針增一」,每當刪除頭元素時,「頭指針增一」。因此,在非空隊列中,頭指針始終指向隊列頭元素,而尾指針始終指向隊尾元素的下一個位置。
循環對列 是將順序隊列變成一個環狀的空間,用這種方法可以解決隊列「假溢出」問題。
「假溢出」 是指隊列實際可用空間沒有占滿,但是不能向隊列中添加新的隊尾元素,否則會出現溢出的現象的情況。
在循環隊列中,頭尾指針以及隊列元素之間的關系不發生改變,只是在循環隊列中頭尾指針「依次循環增一」的操作可用模運算實現。通過取模,頭指針和尾指針就可以在順序表空間內以頭尾銜接的方式「循環」移動。
循環隊列的基本操作演算法描述:
鏈隊是指採用鏈式存儲結構實現的隊列。通常鏈隊用單鏈表來表示,一個鏈隊顯然需要兩個分別指示對頭和隊尾的指針(分別稱為頭指針和尾指針)才能唯一確定。為了操作方便,同線性表的單鏈表一樣,為鏈隊添加頭結點,並規定頭指針始終指向頭結點。
鏈隊列存儲結構表示如下:
鏈隊操作即為單鏈表插入和刪除操作的特殊情況,只是需要進一步修改尾指針或頭指針。
鏈隊列的基本操作演算法描述:
⑦ 關於循環隊列的問題:
其實演算法是這樣的,都是隊尾減去隊頭
比如第一題隊尾減隊頭=10-45=-35,這樣是負的,說明了隊頭跑到了隊尾的後面去了,因為循環的關系這個是正常的,我們只要再加上容量就是答案了-35+50=15
第二題也一樣隊尾減隊頭=29+5這里隊尾本來就在隊頭後面,所以不用加了,就是負的時候要加正的時候不用了,懂了嗎?