佇列的兩種儲存方式的介紹與實現(後續)
阿新 • • 發佈:2019-01-10
簡介
佇列分為順序儲存結構和鏈式儲存結構,鏈式儲存結構其實就是線性表的單鏈表,只是只能在對頭出元素,隊尾進元素而已。從之前實現的佇列的順序儲存結構中我們可以看到他的缺點,我們為了避免“假溢位”就實現迴圈佇列的順序結構,但是迴圈佇列必須指定出佇列的長度,所以說它並不完美。當然我們就可以用鏈式儲存結構
的方式來彌補上述的不足。
實現分析
連結串列是有一個個節點連線而成,每個節點就是一個結構體(value和next指標組成),當然我們得為整個連結串列建立頭指標(front)和尾指標(rear)的指標域.
我們的頭指標中並不存放資料,只是存放一個指向對頭的節點地址,尾指標(rear)指向連結串列的隊尾。當頭指標(front)==尾指標(rear)時,就可以簡單的實現隊空的情況。
如下圖所示:
接下來我們來實現該結構的增刪查等功能,先看一個圖:
/*鏈式儲存結構 *每個節點包含:一個值、一個指向下一個節點的指標 *連結串列結構:由頭指標、尾指標組成一個指標域 *採用鏈式儲存結構的佇列和順序儲存結構區別: *鏈式儲存結構頭指標指向的節點中並不存放資料,只是指向隊頭。 */ typedef struct QueNode{ QueType value; struct QueNode *next; }qNode,*qNodePtr; typedef struct { qNodePtr front; qNodePtr rear; }LinkQueue ; //初始化 int InitLinkQueue(LinkQueue *que){ qNodePtr pNode;//建立一個節點結構指標,分配一個臨時空間 pNode = (qNodePtr)malloc(sizeof(qNode)); que->front = que->rear = pNode; //初始化 return 0; } //判空 int LinkQueueEmpty(LinkQueue *que){ if(que->front == que->rear){ printf("佇列為空\n"); return 0; } return -1; } //增加節點 int EnLinkQueueValue(LinkQueue *que ,QueType Ele){ qNodePtr pNode;//建立一個節點結構指標,分配一個臨時空間 pNode = (qNodePtr)malloc(sizeof(qNode)); pNode->value = Ele; pNode->next = NULL; que->rear->next = pNode; que->rear = pNode;//將尾指標指向新插的節點 return 0; } //刪除節點 int DeLinkQueueValue(LinkQueue * que ,QueType * Ele ){ if(LinkQueueEmpty(que)==0){ printf("刪除節點失敗\n"); return -1; } //佇列中存在有效的節點 qNodePtr pNode;//建立一個節點結構指標,分配一個臨時空間 //將頭指標指向的下一個節點地址賦給pNode節點 pNode = que->front->next; *Ele = pNode->value;//將要刪除的節點值賦值給Ele //將頭指標指向pNode的下一個位置 que->front->next = pNode->next; free(pNode);//釋放記憶體。 return 0; } //連結串列中節點個數 int getLinkQueueSize(LinkQueue *que){ int size = 0; qNodePtr pNode;//建立一個節點結構指標,分配一個臨時空間 pNode = (qNodePtr)malloc(sizeof(qNode)); if(LinkQueueEmpty(que)==0){ printf("連結串列中不存在元素\n"); return 0; } pNode = que->front->next; while(pNode){ size ++; pNode = pNode->next; } free(pNode); return size; } //遍歷連結串列資料 int showLinkQueueList(LinkQueue *que){ if(LinkQueueEmpty(que)==0){ printf("連結串列中不存在元素\n"); return -1; } qNodePtr pNode;//建立一個節點結構指標,分配一個臨時空間 pNode = (qNodePtr)malloc(sizeof(qNode)); pNode = que->front->next; printf("節點資料為\n"); while(pNode){ printf("【%d】\n",pNode->value); pNode = pNode->next; } free(pNode); return 0; }
測試程式碼:
//測試 int main( void){ int ret = 0,size=0; //增加節點 QueType Ele1 = 1; QueType Ele2 = 2; QueType Ele3 = 3; LinkQueue *que; que = (LinkQueue *)malloc(sizeof(LinkQueue)); //初始化 InitLinkQueue(que); ret = EnLinkQueueValue(que ,Ele1); if(ret){ printf("新增節點1失敗\n"); } ret = EnLinkQueueValue(que ,Ele2); if(ret){ printf("新增節點2失敗\n"); } ret = EnLinkQueueValue(que ,Ele3); if(ret){ printf("新增節點3失敗\n"); } //節點個數 size = getLinkQueueSize(que); printf("此時的連結串列節點個數為【%d】\n",size); //刪除一個節點 QueType *Ele = NULL ; QueType ele ; Ele = (QueType*)malloc(sizeof(QueType)); ret = DeLinkQueueValue(que,Ele); if(ret){ printf("刪除節點失敗\n"); } ele = *Ele; //刪除後的節點個數 size = getLinkQueueSize(que); printf("刪除後的節點個數為【%d】\n",size); printf("刪除的節點value為【%d】\n",ele); //遍歷 showLinkQueueList(que); free(Ele); return 0; }
實現結果: