註:本文的主要目的是為了記錄自己的學習過程,也方便與大家做交流。轉載請註明來自:
http://blog.csdn.net/ab198604
對於隊列的實現方式與棧的實現方式類似,也是基於鏈表的操作,所以關於隊列的具體代碼實現也是在原有單向鏈表的基礎之上進一步的封裝後完成。隊列的資料存放區與檢索與棧相反,它主張先進先出,與我們現實生活中的排隊買票類似,第一個先排隊的先買著票,其次才是第二個,第三個......
一、隊列的結構及介面定義
與棧的結構類似,隊列的結構與鏈表的結構一樣,所以用typedef重新命名即可,代碼如下所示:
/* * filename:queue.h * author:zhm * date:2013-01-05 */#ifndef QUEUE_H#define QUEUE_H#include <stdlib.h>#include "list.h"typedef List Queue; //重新命名為隊列Queue
對鏈表有關的定義介面及操作可以登入這個地址查看相關內容:http://blog.csdn.net/ab198604/article/details/8253405
對於隊列的一些相關操作介面聲明如下:
/*public interface */#define queue_init list_init#define queue_destroy list_destroyint queue_enqueue(Queue *queue, const void *data);int queue_dequeue(Queue *queue, void **data);#define queue_peek(queue) ((queue)->head == NULL ? NULL : (queue)->head->data)#define queue_size list_size#endif
與棧的操作類似,它具有隊列的初始化,隊列的銷毀,入列和出列操作等。對於隊列的初始化、銷毀等都是通地typedef語句對鏈表操作介面的重定義。queue_peek此宏用於擷取隊列頭元素data域, queue_size此宏用於擷取隊列中的元數個數。
二、隊列的介面實現細節
由於隊列的初始化及銷毀操作主要是鏈表初始化及銷毀的重定義,所以在此不作說明,可以查看《資料結構學習之單向鏈表》一文。這裡主要是實現隊列的入列和出列操作,其實現的本質在於對鏈表操作的基礎上重新封裝,代碼較簡單,如下:
/* * filename:queue.c * author: zhm * date: 2013-01-05 */#include <stdlib.h>#include <string.h>#include "list.h"#include "queue.h"/* queue_enqueue */int queue_enqueue(Queue *queue, const void *data){ return list_ins_next(queue, list_tail(queue), data);}/* queue_dequeue */int queue_dequeue(Queue *queue, void **data){ return list_rem_next(queue, NULL, data);}
入列操作實際上調用的是鏈表的插入操作函數介面,出列操作則調用的是鏈表的刪除操作函數介面。
三、隊列的具體應用舉例
在本例中,主要的邏輯思路為:先初始化隊列,然後進行入列操作,順序為:0->1->2->3->4,然後執行依次出列操作,出列的順序與入列的順序應該一致。以下是代碼,不多說了,看了就知道:
/* * filename: main.c * author:zhm * date: 2013-01-06 */#include <string.h>#include <stdlib.h>#include <stdio.h>#include "list.h"#include "queue.h"/* destroy */void destroy(void *data){ printf("in destroy\n"); free(data); return;}/* main */int main(int argc, char **argv){ Queue queue; int *int_ptr = NULL; int ret; int i; //init queue queue_init(&queue, destroy); //enqueue; for(i = 0; i < 5; i++ ) { int_ptr = NULL; int_ptr = (int *)malloc(sizeof(int)); if( int_ptr == NULL ) return -1; printf("enqueue: data = %d\n",i); *int_ptr = i; ret = queue_enqueue(&queue, (void *)int_ptr); if( ret != 0 ) return -1; } printf("the size of the queue: %d\n", queue_size(&queue)); for(i = queue_size(&queue); i > 0 ; i-- ) { int_ptr = NULL; ret = queue_dequeue(&queue, (void **)&int_ptr); if( ret != 0 ) return -1; printf("i = %d, dequque data = %d\n",i, *int_ptr); } printf("after dequeue the size of the queue: %d\n",queue_size(&queue)); return 0;}
上述代碼通過編譯後執行,結果如所示:
通過結果可以看出,隊列的出列執行順序與入列時是一致的。完了!~~~