資料結構(c語言)——鏈佇列儲存結構及實現
阿新 • • 發佈:2018-12-16
是佇列鴨,FIFO,先進先出!
對於帶頭節點的和不帶頭節點的鏈佇列的操作有個小小的區別:
不帶頭結點的鏈佇列在入佇列的時候,第一個元素時要先判斷是否為空,再插入。而帶頭結點不需要,操作更方便些;
我是分割線----------------------------------
鏈佇列的結構
typedef struct QNode{ Element data; struct QNode *next; }QNode,*QueuePtr; typedef struct{ // front,就是隊頭,rear就是隊尾 QueuePtr front,rear; }LinkQueue;
鏈佇列的操作(不帶頭節點):
// 判斷棧為空的條件就是隊頭等於隊尾, bool QueueEmpty(LinkQueue *lq){ if (lq->front == lq->rear){ return true; } return false; } // 初始化一個不帶頭節點鏈佇列 LinkQueue* LinkQueueInit(){ LinkQueue *lq; lq = (LinkQueue*)malloc(sizeof(QNode)); lq->front = NULL; lq->rear = NULL; return lq; } // 入佇列,就是單鏈表的尾插法,rear就是尾指標 Status EnQueue(LinkQueue *lq,Element e){ QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); if(!p){ return ERROR; } p->data = e; p->next = NULL; // 判斷是否是一個空的佇列,若是空的佇列,將隊頭和隊尾指向同一節點 if(lq->rear == NULL){ lq->front = lq->rear = p; } else { lq->rear->next = p; lq->rear = p; } return OK; } // 出佇列,從隊頭出,不就和出棧是一樣的嗎 Status DeQueue(LinkQueue *lq,Element *v){ QueuePtr *temp; if(QueueEmpty(lq)){ // QueueEmpty僅僅只是判斷隊頭和隊尾是否指向同一元素節點,當隊頭指向NULL,才說明這個佇列是個空棧佇列 if(lq->front==NULL){ return ERROR; } // 當佇列的隊頭和隊尾都指向同一元素節點的時候,將這個節點出隊後,把隊頭和隊尾都置為空 *v = lq->front->data; temp = lq->front; lq->rear = lq->front = NULL; free(temp); } else { *v = lq->front->data; temp = lq->front; lq->front = lq->front->next; free(temp); } return OK; } void CreateQueue(LinkQueue *lq){ for(int i = 1; i < 5; i++){ EnQueue(lq,i); } } // 清空佇列 void ClearQueue(LinkQueue *lq){ Element e; Element *resP; resP = &e; while(lq->front != NULL){ DeQueue(lq,resP); } } // 列印佇列 void QueuePrint(LinkQueue *lq){ LinkQueue *p = lq; QueuePtr *hn = lq->front; printf("佇列中元素按入隊順序依次為["); while(p->front){ printf("%d",p->front->data); if(p->front->next){ printf(", "); } p->front = p->front->next; } printf("]\n"); lq->front = hn; }
鏈佇列的操作(帶頭節點的):
// 初始化一個帶頭節點鏈佇列 LinkQueue* HLinkQueueInit(){ LinkQueue *lq; // 申請記憶體空間 lq = (LinkQueue*)malloc(sizeof(QNode)); // 將front指向一個空的頭節點 lq->rear = lq->front = (QueuePtr *)malloc(sizeof(QNode)); lq->rear->next = NULL; return lq; } Status HEnQueue(LinkQueue *lq,Element e){ // 就是連結串列的尾插法 QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); if(!p){ return ERROR; } p->data = e; p->next = NULL; lq->rear->next = p; lq->rear = p; return OK; } Status HDeQueue(LinkQueue *lq,Element *v){ QueuePtr temp; if(QueueEmpty(lq)){ return ERROR; } temp = lq->front->next; *v = temp->data; // 這裡的front一直是沒有變過的,指向一個沒有元素的頭節點。 // 變得只是front的next lq->front->next = temp->next; if(p == lq->rear){ lq->rear = lq->front; } free(temp); return OK; } // 其他函式都差不太多,就不貼了
執行結果:
不帶頭的。。。
我是分割線----------------------------