1. 程式人生 > >佇列的兩種儲存方式的介紹與實現(後續)

佇列的兩種儲存方式的介紹與實現(後續)

簡介

佇列分為順序儲存結構和鏈式儲存結構,鏈式儲存結構其實就是線性表的單鏈表,只是只能在對頭出元素,隊尾進元素而已。從之前實現的佇列的順序儲存結構中
我們可以看到他的缺點,我們為了避免“假溢位”就實現迴圈佇列的順序結構,但是迴圈佇列必須指定出佇列的長度,所以說它並不完美。當然我們就可以用鏈式儲存結構
的方式來彌補上述的不足。



實現分析

連結串列是有一個個節點連線而成,每個節點就是一個結構體(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;


}

實現結果: