作者: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
歡迎繼續閱讀“紙上談兵: 算法與數據結構”系列。