1. 程式人生 > >鏈佇列的綜合操作(詳解、演示)C語言實現

鏈佇列的綜合操作(詳解、演示)C語言實現

佇列的簡介

和棧相反,佇列(queue)是一種先進先出(簡稱FIFO)的線性表。它只允許在表的一端進行插入,而在另一端刪除元素。

舉個我們生活中最最常見的例子:銀行排隊(不管什麼排隊),當我們去銀行辦理業務的時候,我們要按照先來後到的規矩,先來的人先處理後面的人候著,先來的人處理完了之後先走…..
根據上面的例子大家應該可以很清楚的理解佇列是什麼了,再來看個示意圖

這裡寫圖片描述

和線性表類似,佇列也有兩種儲存表示
用連結串列表示的佇列稱為鏈佇列、還有一個迴圈佇列在下一篇部落格講。一個鏈佇列顯然需要兩個分別指向隊頭和隊尾的指標(分別稱為頭指標和尾指標)才能唯一確定。這裡,和線性表的單鏈表一樣,為了操作方便起見,我們也給鏈佇列新增一個頭結點,並令頭結點指標指向頭結點,由此。空的鏈佇列的判決條件為頭指標和尾指標均指向頭結點。
鏈佇列的操作即是單鏈表的插入和刪除操作的特殊情況。只需修改頭尾指標即可,下面的程式實現和演示了,佇列的構造、銷燬、清空佇列、銷燬佇列、判斷佇列是否為空、獲得佇列長度、獲得隊頭、入佇列、出佇列、顯示佇列等功能。

/*********************************************************
-  Copyright (C): 2016
-  File name    : queue.c
-  Author       : - Zhaoxinan -
-  Date         : 2016年04月21日 星期四 15時34分59秒
-  Description  : 單鏈佇列的儲存

*  *******************************************************/
#include <stdio.h>
#include
<stdlib.h> #define TRUE 1 #define FALSE -1 #define OK 1 #define ERROR -1 #define OVERFLOW -2 /* ---- 單鏈佇列----佇列的鏈式儲存結構 ---- */ typedef struct Qnode { int date; struct Qnode *next; }QNode,* QueuePtr; typedef struct { QueuePtr head; //隊頭指標 QueuePtr tail; //隊尾指標
}LinkQueue; /* ---- 基本操作函式 ---- */ /* ---- 構造一個空佇列 ---- */ int InitQueue(LinkQueue *Q) { Q->head = Q->tail = (QueuePtr)malloc(sizeof(QNode)); if (Q->head == NULL) { exit(OVERFLOW); } Q->tail->next = NULL; return OK; } /* ---- 銷燬佇列Q,Q不再存在 ---- */ int DestoryQueue(LinkQueue *Q) { //head->node1->node2->node3->tail; // tail // head->node2 while(Q->head) { Q->tail = Q->head->next; free(Q->head); Q->head = Q->tail; } Q->head = Q->tail = NULL; return OK; } /* ---- 將Q清空空佇列 ---- */ int ClearQueue(LinkQueue *Q) { QueuePtr temp; Q->tail = Q->head->next; while(Q->tail) { temp = Q->tail->next; //指向下一個待釋放的單元 free(Q->tail); Q->tail = temp; } Q->tail = Q->head; //修改隊尾指標 return OK; } /* ---- 若佇列Q為空佇列,返回TRUE,否則返回FALSE ---- */ int QueueEmpty(LinkQueue Q) { if (Q.head == Q.tail && Q.head != NULL) { return TRUE; } else { return FALSE; } } /* ---- 返回Q的元素個數,即佇列的長度 ---- */ int QueueLength(LinkQueue Q) { if (Q.head == NULL) { return 0; } QueuePtr temp; int count = 0; temp = Q.head->next; while(temp != NULL) { temp = temp->next; ++count; } return count; } /* ---- 顯示當前佇列的值從隊頭到隊尾 ---- */ void show_queue(LinkQueue Q) { QueuePtr temp; temp = Q.head->next; printf(" 當前佇列從頭到尾:"); while(temp != NULL) { printf("%d ", temp->date); temp = temp->next; } printf("\n"); } /* ---- 若佇列不空,則用e返回Q的隊頭元素,並返回OK, 否則返回ERROR ---- */ int GetHead(LinkQueue Q, int *e) { if (QueueEmpty(Q) == TRUE) { return ERROR; } *e = Q.head->next->date; return OK; } /* ---- 插入元素e為Q的新的對尾元素 ---- */ int EnQueue(LinkQueue *Q, int e) { if (Q->head == NULL || Q->tail == NULL) { return ERROR; } QueuePtr ptr = (QueuePtr)malloc(sizeof(QNode)); if (!ptr) { exit(OVERFLOW); } ptr->date = e; ptr->next = NULL; Q->tail->next = ptr; Q->tail = ptr; return OK; } /* ---- 若佇列不空,則刪除Q的隊頭元素,並用e返回其值,並返回OK,否則返回ERROR ---- */ int DeQueue(LinkQueue *Q, int *e) { if (Q->head == Q->tail) { return ERROR; } /* ptr為臨時變數 */ QueuePtr ptr = (QueuePtr)malloc(sizeof(QNode)); //head->node1->node2->tail; // ptr // head->node2->tail ptr = Q->head->next; *e = ptr->date; Q->head->next = ptr->next; if (Q->tail == ptr) { Q->head = Q->tail; } free(ptr); return OK; } int main() { int i; //迴圈變數 int count; //計數變數 int outque; //出隊元素值 LinkQueue Q; /* 初始化佇列 */ InitQueue(&Q); /* 插入10個元素 */ printf("________________入隊10個元素________________\n\n"); for (i = 0; i < 10; i++) { /* 入隊 */ EnQueue(&Q, i); /* 獲得當前佇列中元素個數 */ count = QueueLength(Q); printf("%2d 入隊_當前佇列中元素個數:%2d",i, count); show_queue(Q); } printf("________________出隊5個元素________________\n\n"); for (i = 0; i < 5; i++) { /* 出隊 */ DeQueue(&Q, &outque); /* 獲得當前佇列中元素個數 */ count = QueueLength(Q); printf("%2d 出隊_當前佇列中元素個數:%2d", outque, count); show_queue(Q); } /* 獲得當前隊頭值 */ GetHead(Q, &outque); printf("\n當前隊頭為:%d\n", outque); printf("________________清空佇列_________________\n\n"); ClearQueue(&Q); count = QueueLength(Q); printf("當前佇列中元素個數:%2d", count); show_queue(Q); printf("________________銷燬佇列_________________\n\n"); DestoryQueue(&Q); count = QueueLength(Q); printf("當前佇列中元素個數:%2d\n\n", count); return 0; }

程式的執行結果

這裡寫圖片描述