1. 程式人生 > >鏈式佇列的定義與操作

鏈式佇列的定義與操作

看程式碼理解。。。

/*************************************************************************
    > File Name: queue.c
    > Author: Netcan
    > Mail: [email protected] 
    > Created Time: 2014/12/21 20:10:02
 ************************************************************************/

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

struct Node { // 定義節點
	int data;
	Node * pNext;
};
struct Queue { // 定義佇列,這裡的pHead是頭指標,不是首指標,指向無效節點
	Node * pHead;
	Node * pTail;
};

void init_Queue(Queue *Q); // 初始化佇列
bool in_Queue(Queue *Q,int val); // 入隊
bool out_Queue(Queue *Q); // 出隊
bool is_empty_Queue(Queue *Q); // 判斷佇列是否為空
int length_Queue(Queue *Q); // 佇列長度
void traverse_Queue(Queue *Q); // 遍歷佇列= =檢測佇列用的
void clear_Queue(Queue *Q); // 清空佇列


int main() {
	Queue Q; // 宣告佇列
	init_Queue(&Q); // 初始化
	in_Queue(&Q,0); // 入隊
	in_Queue(&Q,1);
	in_Queue(&Q,2);
	in_Queue(&Q,3);
	in_Queue(&Q,4);
	in_Queue(&Q,5);
	in_Queue(&Q,6);
	in_Queue(&Q,7);
	in_Queue(&Q,8);
	in_Queue(&Q,9);
	traverse_Queue(&Q); // 遍歷佇列
	printf("Queue length: %d\n", length_Queue(&Q)); // 輸出當前佇列長度
	out_Queue(&Q); // 出隊
	out_Queue(&Q);
	traverse_Queue(&Q);
	printf("Queue length: %d\n", length_Queue(&Q));
	
	puts("Clear Queue"); 
	clear_Queue(&Q); // 清空佇列
	printf("Queue length: %d\n", length_Queue(&Q));
	traverse_Queue(&Q);

	return 0;
}

void init_Queue(Queue *Q) 
{
	Q->pTail = (Node *)malloc(sizeof(Node)); // 使尾指標指向新節點
	Q->pTail->pNext = NULL; // 尾指標指向下一個空節點
	Q->pHead = Q->pTail; // 當前頭指標指向尾指標
	return;
}

bool is_empty_Queue(Queue *Q)
{
	if(Q->pHead == Q->pTail) // 只要頭指標指向尾指標就為空
		return true;
	else
		return false;
}

int length_Queue(Queue *Q)
{ 
	if( is_empty_Queue(Q) )
		return 0;
	int len;
	Node * p = Q->pHead->pNext;  // p指向第一個有效節點
	for(len = 1; p != Q->pTail; len++, p = p->pNext); // 計數,當佇列不為空長度當然大於等於1
	return len;
}

bool in_Queue(Queue *Q,int val)
{
	Node * pNew = (Node *)malloc(sizeof(Node)); // 分配新節點
	if( NULL == pNew )
		return false;
	pNew->data = val; // 新節點的值為入隊的值
	pNew->pNext = NULL; // 新節點從尾部插入則指向下一個空節點
	Q->pTail->pNext = pNew; // 當前尾指標後一個節點指向新節點
	Q->pTail = pNew; // 更新尾指標
	return true;
}

bool out_Queue(Queue *Q) 
{
	if(is_empty_Queue(Q))
		return false;
	Node * p = Q->pHead; // 使p指向頭指標
	Q->pHead = p->pNext;  // 更新頭指標,頭指標下移
	free(p); // 釋放p
	return true;
}

void traverse_Queue(Queue *Q)
{
	if(is_empty_Queue(Q))
		return;
	Node *p = Q->pHead->pNext; // 使p指向第一個有效節點
	while( p != Q->pTail->pNext ) { // 如果p沒到佇列最後一個節點就輸出
		printf("%3d",p->data); 
		p = p->pNext;
	}
	puts("");
	return;
}

void clear_Queue(Queue *Q)
{
	if(is_empty_Queue(Q))
		return;
	Node *p = Q->pHead->pNext; // 使p指向第一個有效節點
	Node *q = p->pNext; // q指向p指向的下一個節點
	while( q != Q->pTail->pNext ) { // 遍歷節點,並清空
		free(p);
		p=q;
		q = p->pNext;
	}
	free(p); // 尾節點清空
	Q->pTail = Q->pHead; // 重置尾指標
}

執行圖: