3.4队列
隊列(queue)是一種先進(jìn)先出 (first in first out縮寫FIFO)的線性表。它只允許在表的一端進(jìn)行插入,而在另一端刪除。類似食堂排隊打飯。允許插入的一端叫做隊尾(rear),允許刪除的一端叫隊頭(front)
如圖3.8所示:
雙端隊列是限定插入和刪除操作在表的兩端進(jìn)行的線性表。一端叫端點1,一端叫端點2
如下圖所示:
用鏈表表示的隊列簡稱鏈隊列。
一個鏈隊列顯然需要兩個分別指示隊頭和隊尾指針,才能確定。
下圖就很好說明了這個例子:
下面是單鏈隊列的結(jié)構(gòu)體
typedef struct QNode{QElemType data;struct QNode *next; }QNode,*QueuePtr;typedef struct LinkQueue{QueuePtr front; //隊頭指針QueuePtr rear; //隊尾指針 }LinkQueue;P·S:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 在xxx.c文件里面要用typedef來簡化機(jī)構(gòu)體,但在.cpp文件里面就不用了。可以直接用
下面是構(gòu)建一個空隊列Q
Status InitQueue(LinkQueue &Q) {Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));if (!Q.front)exit(OVERFLOW); //存儲分配失敗Q.front->next = NULL;return Ok; }
下面是插入元素e為Q的新的隊尾元素
Status EnQueue(LinkQueue &Q, QElemType e) {QNode *p = (QueuePtr)malloc(sizeof(QNode));if (!p)exit(OVERFLOW);p->data = e;p->next = NULL;Q.rear->next = p;Q.rear = p;return Ok; }此函數(shù)思路:把新結(jié)點的next賦值為NULL,在把鏈隊列的尾部的next從以前的next賦值為新結(jié)點的地址。最后把尾部后移成新節(jié)點的地址。
下面是刪除Q的隊頭元素,用e返回其值,并返回OK
Status DeQueue(LinkQueue& Q, QElemType& e) {QNode *p;if (Q.front == Q.rear)return ERROR;p = Q.front->next;e = p->data;Q.front->next = p->next;if (Q.rear == p)Q.rear = Q.front;free(p);return Ok; }這里Q.front==Q.rear就是圖3.11(a)中的空隊列
第二個if里面Q.rear==p是說明如果這里面沒有結(jié)點了,就說明為空隊列時,就Q.rear=Q.front。
循環(huán)隊列-隊列的順序表示和實現(xiàn)
這個有個經(jīng)典題目-圓桌問題
循環(huán)隊列如圖所示:
下面是循環(huán)隊列頭尾指針在不同情況下的不同:
下面是隊列的順序存儲結(jié)構(gòu):
#define MAXQSIZE 100 typedef struct{QElemType *base; //初始化的動態(tài)分配存儲空間int front; //頭指針,若隊列不空,指向隊列頭元素int rear; //尾指針,若隊列不空,指向下一個元素 }SqQueue;
Status InitQueue(SqQueue &Q) {Q.base = (QElemType *)malloc(MAXQSIZE*sizeof(QElemType));if (!Q.base)exit(OVERFLOW);Q.front = Q.rear = 0;return Ok; }
有人會問為什么要(Q.rear-Q.front+MAXQSIZE)%MAXQIZE
舉個例子,因為MAXQSIZE的大小為100,當(dāng)進(jìn)了110個數(shù),又走了20個數(shù)的時候,這時候Q.rear指到10(如果下標(biāo)從0開始),而Q.front指向20,那么Q.rear-Q.front=-10,這時加上MAXQSIZE后就是90再%MAXQSIZE取余后得90,所以這個(Q.rear-Q.front+MAXQSIZE)%MAXQIZE是計算環(huán)形長度的一個好方法。
現(xiàn)在分析下算法:
插入:(Q.rear+1)%MAXQSIZE比如隊列大小是5,那么他們的標(biāo)號為01234號,任何一個數(shù)對5取余都是這5個數(shù),比如01234隊列都滿了,你要插入的話插在4的后邊(5),可是4后邊沒有地方了,這時候?qū)?取余,就得到了0,你就可以插到0的位置了。
第一個if:同理當(dāng)發(fā)現(xiàn)要插入的那個位置正好是Q.front的位置,那么就證明隊列滿了。
同理上面的(Q.front+1)%MAXQSIZE與上面的(Q.rear+1)%MAXQSIZE一模一樣。在此不再解釋
總結(jié)
- 上一篇: MySQL入门之select、from、
- 下一篇: struts2在Action中访问Ses