重提迴圈隊列

來源:互聯網
上載者:User

之前寫過一篇部落格介紹隊列:http://blog.csdn.net/thefutureisour/article/details/7835273

後來發現這個這個隊列是有問題的:

bool enQueue(Queue *q,ElemType e){//如果隊列已滿,重新分配記憶體if(q->rear == q->Qsize-1){q->data = (ElemType*)realloc(q->data,2*q->Qsize*sizeof(ElemType));if(q->data == NULL)return false;elseq->Qsize *= 2;}//先賦值,然後隊尾迴圈加1q->data[q->rear] = e;q->rear = (q->rear+1)%q->Qsize;return true;}

這個判斷隊列滿的辦法明顯是錯誤的,因為有可能在多次出隊、入隊操作以後,data[1]代表rear,data[0]代表front,此時隊列已經滿了應該重新分配記憶體,而這個程式並沒有做出正確的判斷。然後我對作了修改,改成了

if(Qlength(q) == q->Qsize-1)

這個代碼看似正確,但是如果進行下面的測試,就會發現問題了:

int a = 100;Queue myQueue;initQueue(&myQueue,4);//先把隊列充滿for(int i = 0 ; i < 3 ;++i)enQueue(&myQueue,i);printQueue(&myQueue);deQueue(&myQueue,&a);enQueue(&myQueue,3);printQueue(&myQueue);deQueue(&myQueue,&a);enQueue(&myQueue,4);printQueue(&myQueue);enQueue(&myQueue,5);printQueue(&myQueue);destroyQueue(&myQueue);

 

最後一次入隊5以後,列印為空白,通過單步調試,我發現問題因為此時Qlength的傳回值為0.我才恍然大悟,問題的嚴重性:

當data[0]為rear而data[1]為front時,雖然這時候隊列實際已經滿了,我也重新分配了記憶體,但是rear和front下標卻沒有修改,進而導致重新分配的後的數組是類似於下面的結構:

data      0         1         2         3         4         5         6         7

             rear     front    資料   資料    {      新分配的空間      }

首先:enqueue以後rear會++,所以此時會出現Qlength為0,其次這已經完全不是迴圈隊列的結構了,rear的前一個資料是沒有初始化的記憶體。

怎麼解決這個問題呢?

我也沒有特別高明的辦法,只能重新分配的時候建立一個數組,數組中的元素按照隊列從頭至尾的順序儲存,然後重新分配記憶體之後,把新記憶體的前Qsize-1個元素用建立的數組初始化,然後把rear置為Qsize,新來的元素放到rear的位置,然後rear再自增。這樣就搞定了:

bool enQueue(Queue *q,ElemType e){//如果隊列已滿,重新分配記憶體if(q->Qsize-1 == Qlength(q)){//先把原來的按順序記錄在tmp中ElemType* tmp = (ElemType*)malloc(sizeof(ElemType) * q->Qsize);for(int i = 0; i< q->Qsize-1;++i){tmp[i] = q->data[(q->front+i+q->Qsize)%q->Qsize];}//重新分配記憶體q->data = (ElemType*)realloc(q->data,2*q->Qsize*sizeof(ElemType));if(q->data == NULL)return false;//用tmp初始化q->datafor(int i = 0; i< q->Qsize-1;++i){q->data[i] = tmp[i];}//重新設定front、rear標記q->front= 0;q->rear = q->Qsize;//新來的元素放入隊尾q->data[q->Qsize] = e;//隊尾指標自增q->rear++;//容量翻倍q->Qsize *= 2;free(tmp);}else{//先賦值,然後隊尾迴圈加1q->data[q->rear] = e;q->rear = (q->rear+1)%q->Qsize;}return true;}

 

由於時間匆忙,可能會有小的紕漏,但是大方向上應該是沒有問題的。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.