隊列:
含義:是一種先入先出(FIFO)的數據結構。
當我們把數據一個一個放入隊列中。當我們需要用到這些數據時,每次都從隊列的頭部取出第一個數據進行處理。就像排隊進場一樣,先排隊的人先進場。
結構如下圖所示
環形隊列:
含義:它是在寫程序時候一種隊列的特殊表達方式,把隊列數據組中的最后一個元素和第一個元素相連構成環,所以稱為環形隊列。
優點:環形隊列在C/C++編程中首元素出隊后不需要把隊列所有元素向前移動,而取代把把隊首指針向后移動,由於其環形結構,在插入元素后隊尾指針會循環到隊首原來的位置。相對普通隊列的出隊操作減少了大量的運算量。
C語言
程序清單:
本例中包含三個文件:
(插入圖片)
Queue.h:

#ifndef _QUEUE_H #define _QUEUE_H typedef unsigned char uint8_t; typedef int Elem; typedef struct circlequeue { int iLength; int iSize; int iHead; int iTail; Elem *Datas; }Queue; uint8_t Queue_Init(Queue* queue,int size); uint8_t Queue_Delete(Queue *queue); uint8_t isQueueEmpty(Queue *queue); uint8_t isQueueFull(Queue *queue); int Queue_size(Queue *queue); uint8_t Queue_push(Queue *queue,Elem data); Elem Queue_front(Queue *queue); Elem Queue_back(Queue *queue); uint8_t Queue_pop(Queue *queue); void Queue_printf(Queue *queue); #endif
Queue.c:

#include <stdlib.h> #include <stdio.h> #include "Queue.h" /*******************************************************/ /*******************************************************/ /**********************創建隊列*************************/ /*******************************************************/ /*******************************************************/ uint8_t Queue_Init(Queue* queue,int size) { queue->iSize = size; queue->iLength = 0; queue->iTail=0; queue->iHead=0; queue->Datas = (Elem *)malloc(size*sizeof(Elem)); return 1; } /*******************************************************/ /*******************************************************/ /**********************刪除隊列*************************/ /*******************************************************/ /*******************************************************/ uint8_t Queue_Delete(Queue *queue) { free(queue->Datas); return 1; } /*******************************************************/ /*******************************************************/ /*********************隊頭隊尾操作**********************/ /*******************************************************/ /*******************************************************/ static void QueueTailAdd(Queue *queue) { queue->iTail++; queue->iTail = queue->iTail % queue->iSize; } static void QueueHeadAdd(Queue *queue) { queue->iHead ++; queue->iHead = queue->iHead % queue->iSize; } /*******************************************************/ /*******************************************************/ /***********************隊列判空************************/ /*******************************************************/ /*******************************************************/ uint8_t isQueueEmpty(Queue *queue) { if(queue->iLength == 0) { return 1; } return 0; } /*******************************************************/ /*******************************************************/ /***********************隊列判滿************************/ /*******************************************************/ /*******************************************************/ uint8_t isQueueFull(Queue *queue) { if(queue->iLength>=queue->iSize) { return 1; } return 0; } /*******************************************************/ /*******************************************************/ /*******************返回隊列現有長度********************/ /*******************************************************/ /*******************************************************/ int Queue_size(Queue *queue) { return queue->iLength; } /*******************************************************/ /*******************************************************/ /********************往隊尾放入元素*********************/ /*******************************************************/ /*******************************************************/ uint8_t Queue_push(Queue *queue,Elem data) { if(isQueueFull(queue)) { return 0; } queue->Datas[queue->iTail] = data; QueueTailAdd(queue); queue->iLength++; return 1; } /*******************************************************/ /*******************************************************/ /************獲取隊頭第一個元素(不刪除)***************/ /*******************************************************/ /*******************************************************/ Elem Queue_front(Queue *queue) { if(isQueueEmpty(queue)) { return 0; } return queue->Datas[queue->iHead]; } Elem Queue_back(Queue *queue) { if(isQueueEmpty (queue)) { return 0; } return queue->Datas[queue->iTail]; } /*******************************************************/ /*******************************************************/ /******************刪除隊列第一個元素*******************/ /*******************************************************/ /*******************************************************/ uint8_t Queue_pop(Queue *queue) { if(isQueueEmpty(queue)) { return 0;//queue empty } QueueHeadAdd(queue); queue->iLength--; return 1; } /*******************************************************/ /*******************************************************/ /*****************打印隊列中的全部元素******************/ /*******************************************************/ /*******************************************************/ void Queue_printf(Queue *queue) { int i; int temp = queue->iHead; printf("queue datas:\r\n"); for(i=0;i<queue->iLength;i++) { printf("%d ",queue->Datas[temp++%queue->iSize]); } printf("\r\n"); }
main.c(用於測試):

#include <stdlib.h> #include <stdio.h> #include "Queue.h" int main(void) { int i; //queue(stack) Queue queue2[20]; //queue(heap) Queue *queue = (Queue*)malloc(sizeof(Queue)*20); //Queue Init Queue_Init(queue,20); Queue_Init(queue2,20); //queue1 printf("insert datas:(0-19)\r\n"); for(i=0;i<20;i++) { Queue_push(queue,i); } Queue_printf(queue); printf("delete datas(first 10):\r\n"); for(i=0;i<10;i++) { Queue_pop(queue); } Queue_printf(queue); printf("first data:%d\r\n",Queue_front(queue)); printf("queuesize = %d\r\n",Queue_size(queue)); //queue2 printf("\r\n"); printf("insert datas to queue2:(0-190,10interval)\r\n"); for(i=0;i<20;i++) { Queue_push(queue2,i*10); } Queue_printf(queue2); printf("delete datas(first 10):\r\n"); for(i=0;i<10;i++) { Queue_pop(queue2); } Queue_printf(queue2); //delete queue printf("\r\n"); printf("queue1 delete\r\n"); Queue_Delete(queue); free(queue); queue=0; printf("queue2 delete\r\n"); Queue_Delete(queue2); system("pause"); return 0; }
測試結果:
函數詳解:
環形隊列結構體:
在循環隊列中,有以下參數
必要參數:
- 數據 *Datas;
- 對尾索引 iTail;
- 隊頭索引 iHead;
可選參數:
- 隊列總大小 iSize;//隊列最大存放量,防止不當操作造成堆棧溢出
- 隊列現在的長度 iLength;//儲存現在的長度減少運算量(不定義此參數可以通過隊頭隊尾索引差值計算長度)
typedef struct circlequeue { int iLength; int iSize; int iHead; int iTail; Elem *Datas; }Queue;
創建隊列:
- 設置隊列的最大長度;
- 把隊列中的其他參數清零;
- 為隊列的數據區域申請內存;
uint8_t Queue_Init(Queue* queue,int size) { queue->iSize = size; queue->iLength = 0; queue->iTail=0; queue->iHead=0; queue->Datas = (Elem *)malloc(size*sizeof(Elem)); return 1; }
入隊操作:
- 判斷隊列是否已滿,滿則無法插入,返回0插入失敗;
- 往隊尾插入數據
- 隊尾索引增加
- 隊列長度增加
uint8_t Queue_push(Queue *queue,Elem data) { if(isQueueFull(queue)) { return 0; } queue->Datas[queue->iTail] = data; QueueTailAdd(queue); queue->iLength++; return 1; }
出隊操作(分為兩部分)
出隊細分一、獲取隊頭元素但不刪除
- 判斷隊列是否為空,空則獲取失敗返回0;
- 返回隊列中隊頭索引指向元素
Elem Queue_front(Queue *queue) { if(isQueueEmpty(queue)) { return 0; } return queue->Datas[queue->iHead]; }
出隊細分二、刪除隊頭的元素但不返回其值
- 判斷隊列是否為空,空則刪除失敗;
- 增加隊頭索引;
- 減少隊列長度;
uint8_t Queue_pop(Queue *queue) { if(isQueueEmpty(queue)) { return 0;//queue empty } QueueHeadAdd(queue); queue->iLength--; return 1; }
打印隊列中的元素、
創建一個temp等於隊頭索引,后邊打印中使用;
循環打印iLength(隊列長度)個數據;
從隊頭(temp)指向的元素開始打印,每打印一個數據后temp++(指向下一個元素),(特別說明:temp%queue->iSize取余數,當temp索引超過最大長度時自動返回數組頭開始打印,temp++%queue->iSize相當於兩步1、temp%queue->iSize 2、temp++)
void Queue_printf(Queue *queue) { int i; int temp = queue->iHead; printf("queue datas:\r\n"); for(i=0;i<queue->iLength;i++) { printf("%d ",queue->Datas[temp++%queue->iSize]); } printf("\r\n"); }
C++語言
C++中思路和C基本類似,這里就不在贅述。上程序:
程序清單:
本部分包含三個文件:
(此處插入圖)