1. 程式人生 > >用連結串列實現佇列--鏈式佇列

用連結串列實現佇列--鏈式佇列

/*
  一、關於鏈式佇列的約定(目的是在C語言中描述方便)
  1.定義:
  (1)佇列是一種先進先出的線性表;
  (2)它只允許在表的一端進行入隊,在另一端進行出隊操作。在佇列中,允許插入的一端
       叫隊尾,允許刪除的一端較隊頭,即入隊只能從隊尾入,出隊只能從隊頭出;
  (3)運算受限的非迴圈單鏈表,頭尾結點都有,連結串列中的插入刪除操作在這裡只能在隊頭
       隊尾進行。
  (4)對頭指標指向有效資料,並且可移動;隊尾指標指向的結點不存有效資料,指標域
       指向空NULL,永不移動。
  
  2.建立鏈式佇列時:需定義兩個結構,一個用於描述結點(此結構跟連結串列結點對應的結構類
    似),一個用於描述式哪個佇列(此結構包括隊頭和隊尾指標);與建立一個空連結串列類似。
    隊頭指標和隊尾指標都指向不存放有效資料的頭結點,此頭結點的指標域指向NULL。

  3.入隊,出隊,編歷,判斷是否為空(鏈式佇列不存在滿問題),清空佇列等操作。
  
  4.在C語言中不能使用動態分配的一維陣列來實現迴圈佇列。如果使用者程式中有迴圈佇列,則必須為它設定一個最大佇列長度,若使用者無法預估所用佇列最大長度,則宜採用鏈佇列。
*/

#include "LinkedQueue.h"

void linkedQueueCreat(struct linkedQueue *qQ)
{
	qQ->pFront = (struct linkedQueueNode *)malloc(sizeof(struct linkedQueueNode));
	if( NULL == qQ->pFront )
	{
		printf("linkedQueueCreat(): malloc failed!\n");
		exit(-1);	
	} 
	qQ->pRear = qQ->pFront;
	qQ->pRear->pNext = NULL;
	return;
}

//入隊,鏈式佇列不存在滿的情況
void enLinkedQueue(struct linkedQueue *qQ,int val)
{
	struct linkedQueueNode * pNew = (struct linkedQueueNode *)malloc(sizeof(struct linkedQueueNode));
	if( NULL == pNew )
	{
		printf("enLinkedQueue(): malloc failed!\n");
		exit(-1);	
	} 

	pNew->data = val;
	qQ->pRear->pNext = pNew;//從隊尾入,把pNew指向的結點掛到佇列尾部
	pNew->pNext = NULL;
	qQ->pRear = pNew;//尾指標上移

	return;
	
}

int linkedQueueEmpty(struct linkedQueue *qQ)
{
	if( qQ->pFront == qQ->pRear)
	    return 1;
	else
	    return 0;
}

//出隊,要判斷是否為空
void outLinkedQueue(struct linkedQueue *qQ,int *pVal)
{
	if( linkedQueueEmpty(qQ) )
	{
		printf("linkedQueue is Empty!\n");
		return;
	}
	
	struct linkedQueueNode * pTemp = qQ->pFront->pNext;//從隊頭出隊,pHead指向的結點不出隊,這個結點沒有實際意義。隊首結點是pHead->pNext指向的結點。
	*pVal = pTemp->data;
	qQ->pFront->pNext = pTemp->pNext;
	free(pTemp);
	
	if( NULL == qQ->pFront->pNext )
	{
		qQ->pFront = qQ->pRear;//當佇列最後一個元素被刪除後,佇列尾指標也丟失了,因此需對隊尾指標重新賦值,即指向頭結點。
	}

	return;
}

//遍歷佇列,並返回佇列的長度
void traverseLinkedQueue(struct linkedQueue *qQ,int *linkedQueueLen)
{
	int i=0;
	struct linkedQueueNode * pTemp = qQ->pFront->pNext;
	
	while( pTemp != NULL )
	{
		i++;
		printf("data-%d is %d\n",i,pTemp->data);
		pTemp = pTemp->pNext;
	}
	
	*linkedQueueLen = i;
	
	return;
}

//清空佇列,使其變為空佇列,框架還在
int clearLinkedQueue(struct linkedQueue *qQ)
{
	int pVal=0;

	while( !(linkedQueueEmpty(qQ)) )
           outLinkedQueue(qQ,&pVal);	
	
	return;
}

相關標頭檔案:

#ifndef LINKEDQUEUE_H
#define LINKEDQUEUE_H

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

struct linkedQueueNode 
{
	int data;
	struct linkedQueueNode *pNext;
};

struct linkedQueue
{
	struct linkedQueueNode * pFront;
	struct linkedQueueNode * pRear;
};

void linkedQueueCreat(struct linkedQueue *qQ);
void enLinkedQueue(struct linkedQueue *qQ,int val);
int linkedQueueEmpty(struct linkedQueue *qQ);
void outLinkedQueue(struct linkedQueue *qQ,int *pVal);
void traverseLinkedQueue(struct linkedQueue *qQ,int *linkedQueueLen);
int clearLinkedQueue(struct linkedQueue *qQ);

#endif