C语言队列的理解
? ?隊列是一種特殊的線性表,特殊之處在與允許在表的前端(front)進行刪除操作,而在表ide后端進行插入操作,和棧一樣,隊列時一種操作受限制的線性表,進行
插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。
? 隊列的數據元素稱為隊列元素,在隊列中插入一個隊列元素稱為入隊,從隊列中刪除一個隊列元素稱為出隊,因為隊列只允許在一段插入,一端刪除,所以只有最早進入隊列
的元素才能從隊列中刪除,故隊列由稱為先進先出(fifo)
? 順序隊列
? ? ?建立順序隊列結構必須為其靜態分配或動態申請一片連續的存儲空間,并設置兩個指針進行管理,一個是隊頭指針front,它指向隊頭元素,一個是隊尾指針rear,它指向下一個入隊元素,位置,每次在隊尾插入一個元素,rear增加1;每次在隊頭刪除一個元素,front增加1,隨著插入和刪除的操作進行,隊列元素的各數不斷變化,隊列占的存儲空間在隊列結構分配的連續空間中移動,當Front=rear時,隊列中每有任何元素,稱為空隊列,當rear增加到指向分配的連續空間之外,隊列無法在插入新元素,但這時往往還有大量的可用的空間未被占用,這些空間是已經出對的隊列元素占用過的存儲單元。
? ? 隊尾指針指向隊尾元素的下一個位置(也可以讓rear指向隊尾元素,front指向隊頭元素的前一個位置,)
 
循環隊列
? ?在實際使用隊列時,為了使隊列空間能重復使用,往往對隊列的使用方法稍加改進,無論插入或刪除,一旦rear指針增加1或front指針增加1時超出分配的隊列空間,就讓它執行這片連續空間的起始位置,自己真從MaxSize-1曾1變到0,可用取運算rear% Maxsize和Front%MaxSize來實現,這實際上是吧隊列空間想象成一個環形空間,環形空間中存儲短語循環使用,用這種方法管理的隊列稱為循環隊列,
在循環隊列中,當隊列為空時,有front=rear,而當所有隊列空間全占滿,也有front=rear,為了區別這兩種情況,規定循環隊列最多只能有MaxSize-1個隊列元素,當循環隊列中只剩一個存儲單元時,隊列就已經滿了,因此,隊列判空時front=rear,而隊列判滿時front=(rear+1)%MaxSize.
 
typedef struct QNode{
? ElemType data;
? struct QNode *next;
}QNode;
 
typedef struct LinkQueue{
? QNode *front; ? ? ?//指向隊頭元素
? QNode *rear; ? ?//指向隊尾元素
}LinkQueue;
 
?Status InitQueue(LinkQueue *q)
{
? ? q->front=q->rear=(QNode*)malloc(sizeof(QNode)); ? //分配內存空間
? ? ? ?if(!q->front)
? ? ? ? ?return error;
? ? ? q->front->next=null;
? ? return OK;
}
 
Status EnQueue(LinkQueue *q,ElemType e) ? //插入隊列
{
? ? QNode *p=(QNode*)malloc(sizeof(QNode));
? ? if(!p)
? ? ? return error;
? ? p->data=e;
? ?p->next=null;
? ?p->rear->next=p; ? //將新地址保存,入隊操作,從隊尾(rear)進入
? ?q->rear=p; ? //相當于rear++,q->rear指向下一個位置 ?符合入隊操作的基本要求
? ?return OK;
}
 
Status DeQueue(LinkQueue *q,ElemType *e)
{
? ? QNode *p=(QNode *)malloc(sizeof(QNode));
? ? if(!p)
? ? ? return error;
? ? p=q->front->next;//q 指向的是Front指針的下一個位置,即隊首元素。
? ?*e=p->data;
? ?q->front->next=p->next;//出隊操作后,Front++
? ?if(q->rear==p)//判斷是否全部出隊
? ? ? ?q->rear=q->front;//如果全部出隊,則將隊列置為空
? return ok;
? ??
}
 
在循環隊列中,Q->front==Q->rear并不能確定隊列為空,也有可能是隊列已滿,所以采用隊列頭指針在隊尾指針的下一位置來判斷隊列已滿(此方法會浪費一個內存空間)。
 
#define MAXQSIZE ?100
typedef struct
{
? ? QElemType *base;
? ?int front;
? ?int rear;
? ?int queuesize;
 
}SqQueue;
 
Status InitQueue(SqQueue *Q)
{
? ? Q->queuesize=MAXQSIZE;
? ? Q->base=(QElemType*)malloc(Q->queuesize *sizeof(QElemType));
? ? if(Q->base==NULL)
? ? {
return ERROR;
? ? ?}
? ? Q->front=Q->rear=0;
? ? ?return OK;
}
int QueueLength(SqQueue *Q)
{
? ? ? return((Q->rear-Q->front+Q->queuesize)%Q->queuesize);
}
Status EnQueue(SqQueue *Q,QEletype e)
{
//在循環隊列中,Q->front==Q->rear并不能確定,隊列為空,也有可能是隊列已滿
//所以采用隊列頭指針在隊尾指針的下一位置來判斷隊列已滿
? if((Q->rear+1)%Q->queuesize==Q->front)
?{
? ? ? Q->base =(QElemType*)realloc(Q->base,Q->queuesize);
? ? if(Q->base==null)
? ? ? return error;
? ? ?Q->queuesize*=2;
?}
? Q->bse[Q->rear]=e;
? Q->rear=(Q->rear+1)%Q->queuesize;
? ?return OK;
}
 
Status DeQueue(SqQueue *Q,QElemType *e)
{
? ?if(Q->front==Q->rear)
? ?{
? ? ? return error;
? ?}
? ?*e=Q->base[Q->front];
? ?Q->front=(Q->front+1)%Q->queuesize;
? ?return OK;
}
Status DestroyQueue(SqQueue*Q)
{
? ? free(Q->base);
? ? ?return OK;
}
int main()
{
? ?SqQueue Q;
? ?QElemType e;
? ? int i;
? ? InitQueue(&Q)
? ?for(i=0;i<MAXQSIZE*10;++i)
? {
? ? ? if(EnQueue(&Q,i)!=OK)
? ? ? ? ?return -1;
? ? ?while(Q.front!=Q.rear)
? ? ? ?{
DeQueue(&Q,&e);
? ? ? ? ? ? ? ? printf("%d\n",e);
? ? ? ?}
? ? DestroyQueue(&Q);
? ? return 0;
? }
}
 
 
 
 
 
 
 
總結
 
                            
                        - 上一篇: Java Io
- 下一篇: 安卓从入门到进阶推荐学习方法与书籍整理(
