1.1 linkqueue.h
#ifndef LINKQUEUE_H #define LINKQUEUE_H #include <stdio.h> #include <malloc.h> typedef enum { OK=0, //正確 ERROR=1, //出錯 TRUE=2, //為真 FALSE=3 //為假 }status; typedef int ElemType; //宏定義隊列的數據類型 /* 鏈式隊列:是指采用鏈式存儲結構的隊列,隊列中每一個元素對應鏈表中的結點。 * 和鏈式棧類似,一般采用單鏈表來實現鏈式隊列。 *************************************************************/ // 鏈式隊列結點結構 typedef struct Node { ElemType data; //結點數據 //【負責建立隊列各結點之間的聯系,前一個結點的next指向后一個結點,形成鏈式隊列】 struct Node *next; //后繼結點 }LQNode; // 鏈式隊列結構 typedef struct { LQNode *front; //鏈式隊列的隊頭指針,總是指向隊列的頭結點(出隊一次,第二個結點變為頭結點) LQNode *rear; //鏈式隊列的隊尾指針,入隊時指向新插入結點(總是指向隊列的最后一個結點) }LinkQueue; //創建空隊列 status initQueue(LinkQueue *pQHead); //銷毀隊列 void destroyQueue(LinkQueue *pQHead); //清空隊列 void clearQueue(LinkQueue *pQHead); //判斷隊列是否為空 status isEmpityQueue(LinkQueue *pQHead); //獲得隊列長度 int getQueueLen(LinkQueue *pQHead); //新元素入隊 [先進先出原則:在隊尾的位置插入] element-要插入元素 status enQueue(LinkQueue *pQHead,ElemType element); //新元素出隊,同時保存出隊的元素 [先進先出原則:在隊頭的位置刪除] status deQueue(LinkQueue *pQHead,ElemType *pElement); //遍歷隊列 void queueTraverse(LinkQueue *pQHead); #endif // LINKQUEUE_H
1.2 linkqueue.c
#include "linkqueue.h" /********************************************************************* * 剛開始創建空隊列時,隊列的隊頭和隊尾指針相等都指向頭結點,頭結點的數據域不存放數據 * 第一次入隊,創建新結點,其數據域保存新插入元素,頭結點的next指向新結點, * 並且隊列的隊尾指針指向新結點,隊列的隊頭指針仍然指向頭結點,依次類推 * 第一次出隊,則隊列的隊頭指針指向頭結點的next,依次類推 *********************************************************************/ //創建空隊列: pQHead即為隊列頭結點 status initQueue(LinkQueue *pQHead) { //隊列頭結點的隊頭和隊尾指針申請內存 pQHead->front = pQHead->rear = (LQNode*)malloc(sizeof(LQNode)); if(!pQHead->front) //檢測是否申請失敗 { printf("pQHead->front malloc error!\n"); return ERROR; } //設置頭結點指針域為空 pQHead->front->next = NULL; return OK; } //銷毀隊列 void destroyQueue(LinkQueue *pQHead) { free(pQHead->front); free(pQHead->rear); pQHead->front = pQHead->rear = NULL; } //清空隊列 void clearQueue(LinkQueue *pQHead) { pQHead->front = pQHead->rear; } //判斷隊列是否為空 status isEmpityQueue(LinkQueue *pQHead) { //隊頭指針與隊尾指針相等,說明隊列為空 if(pQHead->front == pQHead->rear) return TRUE; return FALSE; } //獲得隊列長度 int getQueueLen(LinkQueue *pQHead) { LQNode *temp = pQHead->front; int length = 0; while(temp != pQHead->rear) { ++length; temp = temp->next; } return length; } //新元素入隊:即鏈式隊列的尾結點指針,指向存放新元素的新結點 status enQueue(LinkQueue *pQHead, ElemType element) { //創建新結點,並申請內存 LQNode *temp = (LQNode*)malloc(sizeof(LQNode)); if(!temp) { printf("temp malloc error!\n"); return ERROR; } temp->data = element; //將要插入元素存入新結點的數據域內 temp->next = NULL; //隊列只能從隊尾插入所以下一個結點初始化為NULL //鏈式隊列元素為結點(LQNode) //pQHead->rear為隊列的最后一個結點,當插入新結點temp時,pQHead->rear->next = temp //使前一個結點的next指向新結點,建立隊列各結點之間的聯系 pQHead->rear->next = temp; //將隊尾結點的后繼指針指向新結點,如果第一次入隊, //則pQueue->rear->next相當於pQueue->front->next // pQHead->rear總是指向隊列的最后一個結點 pQHead->rear = temp; //將隊尾結點的指針指向新結點temp,temp變為最后一個結點 return OK; } status deQueue(LinkQueue *pQHead,ElemType *pElement) { //如果隊列為空,則返回ERRIR if(isEmpityQueue(pQHead)==TRUE) { printf("queue is NULL!\n"); return ERROR; } //值入隊一次后就出隊,則pQueue->front->next==pQHead->rear->next,為第一個插入的結點 LQNode *temp = pQHead->front->next; //初始化temp為要出隊的結點的指針 //如果要出隊的結點為最后一個結點,使q->rear指向頭結點防止出現懸空的指針 if(pQHead->front->next == pQHead->rear) pQHead->rear = pQHead->front; *pElement = temp->data; //將出隊的數據元素存入*e pQHead->front->next = temp->next; //使下一個結點成為隊頭,如果沒有下一個結點則為NULL free(temp); //刪除要出隊的結點 temp = NULL; return OK; } //遍歷隊列 void queueTraverse(LinkQueue *pQHead) { //如果隊列為空 if(isEmpityQueue(pQHead)==TRUE) { printf("\nqueue is NULL!\n"); } LQNode *temp = pQHead->front; printf("將隊列中的所有元素出隊:\n"); while(temp != pQHead->rear) { temp = temp->next; printf("%d ", temp->data); } printf("\n"); }
1.3 main.c
/********************************************* * C實現鏈式隊列 2017/10/26 by nieXianFeng *********************************************/ #include <stdio.h> #include "linkqueue.h" int main() { int value; //用於保存出隊的元素 //給頭結點申請內存 LinkQueue *pQHead= (LinkQueue*)malloc(sizeof(LinkQueue)); if(!pQHead) //檢測是否申請失敗 { printf("pQHead malloc error!\n"); return ERROR; } //調用初始化隊列的函數 initQueue(pQHead); //調用出隊函數 enQueue(pQHead, 1); enQueue(pQHead, 2); enQueue(pQHead, 3); enQueue(pQHead, 4); enQueue(pQHead, 5); enQueue(pQHead, 6); enQueue(pQHead, 7); enQueue(pQHead, 8); //調用遍歷隊列的函數 queueTraverse(pQHead); //調用出隊函數 if(deQueue(pQHead, &value)==OK) { printf("出隊一次,元素為:%d\n", value); } queueTraverse(pQHead); if(deQueue(pQHead, &value)==OK) { printf("出隊一次,元素為:%d\n", value); } queueTraverse(pQHead); printf("隊列長度是%d\n",getQueueLen(pQHead)); clearQueue(pQHead); //清空隊列 queueTraverse(pQHead); free(pQHead); pQHead = NULL; return 0; }