標籤:height pre nod push typedef else turn 語言 模板
把以前寫的東西貼在這裡方便回故
以前我們建立一個隊列.一開始介面不太友好.後來我們進行了最佳化.
Queue abc; //聲明隊列結構體crteate_Queue(abc); //建立隊列abc.push(int num); //壓入int abc = abc.pop();//彈出
大致是這樣子的.但是我們發現,這個隊列有一個非常明顯的缺陷.那就是,只能push進int型的變數,如果我們想要壓進去其它類型.甚至是自訂類型.那麼,我們就得對這個隊列程式進行大刀闊斧似的改變.幾乎所有的代碼都改了,但是代碼的邏輯卻是一模一樣,讓人"捉急",不甘心,邏輯一模一樣的代碼,每次改變類型,我們需要去修改大部分代碼才能使用,這樣的程式是我們不想要的.所以我們需要一個通用的隊列,它的目標是: 1.我們不需要去修改隊列的代碼.2.它能push進任何類型 如果在C++,有模板類,可以很容易解決這個問題,但是在C裡,我們只好想一個巧妙的辦法來完成這個任務. 首先,我們只考慮隊列,它的資料結構是這樣的:
typedef struct _Node{ struct _Queue * prev; struct _Queue * next;}Node;typedef Node* Node_Pion; //它的指標類型
然後是它的行為:
Node_Pion node_push(Node_Pion tail, Node_Pion node) //給我一個尾指標,一個結點.{ if (!node) return NULL; if(tail) tail-next = node; node->prev = tail; tail = node; return tail;}Node_Pion node_pop (Node_Pion head) //給我一個頭指標.{ if(head-next) head->next->prev = NULL; head = head->next; return head; }
從上面看出,這裡和昨天並無什麼 太大的區別. 下面是關鍵.. 然後我們對這個隊列進行封裝:
typedef struct _Queue{ Node_Pion HEAD; //它的頭 Node_Pion TAIL; //它的尾}Queue;typedef Queue* Queue_pion;//它的行為//構造Queue_pion ctreate_queue(Queue_pion queue){ if(!queue) queue = (Queue_pion)malloc(sizeof(_Queue)); queue->HEAD = NULL; queue->TAIL = NULL;return queue;}//析構void delete_queue(Queue_pion queue){ free(queue);}//壓入void push (Queue_pion queue, void* node){ if((!queue->HEAD) && (!queue->TAIL)) //如果頭尾有一個等於NULL.隊列無效 queue->TAIL = queue->HEAD = node_push(queue->TAIL, (Node_Pion)node); //重建立立隊列 else queue->TAIL = node_push(queue->TAIL, (Node_Pion)node); //給我一個尾指標,一個結點.}//彈出void* pop (Queue_pion queue){ Node_Pion p = queue->HEAD; queue->HEAD = node_pop(queue->HEAD); return (void*)p;}
這樣,我們在使用時就比較好玩了 比如,我們有一個自訂的類型
struct abc{ int num; int val;};
然後,我們在代碼裡,構造一個隊列:
Queue *abc = ctreate_queue(Queue_pion queue); typedef struct _abc{ Node node; //我們在這個自訂結構裡的第一個元素,加上我們的結點結構的一個元素. int num; int val;}*abc; 還是起個好用的名字吧.
abc p=(abc)malloc(sizeof(_abc)); // 申請一個新對象 push(bgd,p); //這樣就可以壓入隊列了 pop(bgd) ; //這樣就可以彈出了,更簡單
C語言簡單隊列