紙上談兵: 隊列 (queue)


作者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉載,也請保留這段聲明。謝謝!

 

隊列(queue)是一個簡單而常見的數據結構。隊列也是有序的元素集合。隊列最大的特征是First In, First Out (FIFO,先進先出),即先進入隊列的元素,先被取出。這一點與棧(stack)形成有趣的對比。隊列在生活中很常見,排隊買票、排隊等車…… 先到的人先得到服務並離開隊列,后來的人加入到隊列的最后。隊列是比較公平的分配有限資源的方式,可以讓隊列的人以相似的等待時間獲得服務。

 

隊列支持兩個操作,隊首的元素離開隊列(dequeue),和新元素加入隊尾(enqueue)

隊列

 

隊列在計算機中應用很廣泛。一個經典的應用是消息隊列(參考Linux進程間通信),實際上就是利用隊列來分配有限的進程。還有FIFO文件(哦,你可以看到,這種文件叫做FIFO,肯定是和隊列有關),用以實現管道傳輸。再比如,我們將多個打印任務發送給打印機,打印機也是使用隊列來安排任務的順序。

 

隊列的C實現 (基於表)

和棧相似,隊列也可以有多種實現方式,這里是基於單鏈表的實現。

表(list)中的實現方式略有不同的是,這里的head node有兩個指針,一個(next)指向下一個元素,一個(end)指向隊列的最后一個元素。這樣做的目的是方便我們找到隊尾,以方便的進行enqueue操作。我們依然可以使用之前定義的表,在需要找到隊尾的時候遍歷搜索到最后一個元素。

用於隊列的表

下面是代碼:

/* By Vamei */
/* use single-linked list to implement queue */ #include <stdio.h> #include <stdlib.h> typedef struct node *position; typedef int ElementTP; // point to the head node of the list
typedef struct HeadNode *QUEUE; struct node { ElementTP element; position next; }; /* * CAUTIOUS: "HeadNode" is different from "node", * it's another struct * end: points to the last value in the queue */
struct HeadNode { ElementTP element; position next; position end; }; /* * Operations */ QUEUE init_queue(void); void delete_queue(QUEUE); void enqueue(QUEUE, ElementTP); ElementTP dequeue(QUEUE); int is_null(QUEUE); /* * Test */
void main(void) { ElementTP a; int i; QUEUE qu; qu = init_queue(); enqueue(qu, 1); enqueue(qu, 2); enqueue(qu, 8); printf("Queue is null? %d\n", is_null(qu)); for (i=0; i<3; i++) { a = dequeue(qu); printf("dequeue: %d\n", a); } printf("Queue is null? %d\n", is_null(qu)); delete_queue(qu); } /* * initiate the queue * malloc the head node. * Head node doesn't store valid data * head->next is the first node in the queue. */ QUEUE init_queue(void) { QUEUE hnp; hnp = (QUEUE) malloc(sizeof(struct HeadNode)); hnp->next = NULL;  // qu->next is the first node
    hnp->end  = NULL; return hnp; } /* * dequeue all elements * and then delete head node */
void delete_queue(QUEUE qu) { while(!is_null(qu)) { dequeue(qu); } free(qu); } /* * enqueue a value to the end of the queue */
void enqueue(QUEUE qu, ElementTP value) { position np, oldEnd; oldEnd = qu->end; np = (position) malloc(sizeof(struct node)); np->element  = value; np->next     = NULL; /* if queue is empyt, then oldEnd is NULL */
    if (oldEnd) { oldEnd->next = np; } else { qu->next     = np; } qu->end = np; } /* * dequeue the first value */ ElementTP dequeue(QUEUE qu) { ElementTP element; position first, newFirst; if (is_null(qu)) { printf("dequeue() on an empty queue"); exit(1); } else { first = qu->next; element = first->element; newFirst = first->next; qu->next     = newFirst; free(first); return element; } } /* * check: queue is empty? */
int is_null(QUEUE qu) { return (qu->next == NULL); }

 

運行結果如下:

Queue is null? 0
dequeue: 1
dequeue: 2
dequeue: 8
Queue is null? 1

 

總結

隊列,FIFO

enqueue, dequeue

 

歡迎繼續閱讀“紙上談兵: 算法與數據結構”系列。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM