數據結構學習(七)——鏈隊列的操做

隊列的存儲方式除了有順序隊列,還能夠有鏈隊列這種形式。鏈隊列是採用鏈式結構存儲的隊列,相似單鏈表,但操做受限制,只容許在表頭刪除結點和在表尾插入結點。node

在鏈隊列中,除了有一個頭指針外,還要有一個尾指針。在隊頭還須要加一個頭結點,當隊列爲空時,頭指針與尾指針同時指向頭結點。爲了與頭結點區分開,稱隊列的第一個結點(頭結點後面的第一個結點)爲隊頭結點。指針

下面的代碼就是對鏈隊列的一些操做,其中有個問題還讓我糾結了會兒。code

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

typedef struct list
{
	char data;
	struct list *next;
}linklist;

typedef struct node
{
	linklist *front;					
	linklist *rear;
}linksequeue;	//鏈隊列

linksequeue *Linksequeue_CreateEnd();				//尾插法建立鏈隊列
char Linksequeue_GetFront(linksequeue *q);			//取得頭結點
void Linksequeue_In(linksequeue *q, char dat);		//入隊
char Linksequeue_Out(linksequeue *q);				//出隊
void ShowLinksequeue(linksequeue *q);				//輸出顯示隊列

int main(void)
{
	linksequeue *q;
	int choice;
	char ch, ans;

	printf("鏈隊列的操做練習:\n");
	printf("依次輸入隊列結點數據('#'號表示結束):\n");
	q = Linksequeue_CreateEnd();
	getchar();

	while(1)
	{
		printf("鏈隊列操做:\n");
		printf("1.取頭結點\n");
		printf("2.入隊\n");
		printf("3.出隊\n");
		printf("4.輸出顯示隊列\n");
		printf("5.退出程序\n");
		printf("作出選擇:\n");
		scanf("%d", &choice);
		getchar();					//消除回車鍵帶來的影響

		switch(choice)
		{
		//取頭結點
		case 1:
			ch = Linksequeue_GetFront(q);
			if(ch)
				printf("頭結點爲%c\n",ch);
			else
				printf("取頭結點失敗!\n");
			break;
		//入隊
		case 2:
			printf("輸入想入隊的字符數據:");
			scanf("%c", &ch);
			Linksequeue_In(q, ch);
			break;
		//出隊
		case 3:
			ans = Linksequeue_Out(q);
			if(ans != '\0')
			{
				printf("出隊成功!\n");
				printf("出隊數據爲%c\n", ans);
			}
			else
				printf("出隊失敗!\n");
			break;
		//輸出顯示隊列
		case 4:
			ShowLinksequeue(q);
			break;
		//退出程序
		case 5:
			return 0;
			break;
		default:
			printf("選擇無效!\n");
			break;
		}
	}
	return 1;

}

//鏈隊列置空
void Linksequeue_SetNull(linksequeue *q)
{
	q->front = (linklist*)malloc(sizeof(linklist));
	q->front->next = NULL;		//隊頭結點爲空,尾結點指向頭結點
	q->rear = q->front;
}

//判斷鏈隊列是否爲空
int Linksequeue_Empty(linksequeue *q)
{
	if(q->front == q->rear)		//頭結點等於尾結點則爲空
		return 1;
	else
		return 0;
}

//建立鏈隊列
linksequeue *Linksequeue_CreateEnd()
{
	linksequeue *q;
	char ch;
 
	q = (linksequeue*)malloc(sizeof(linksequeue));		//關鍵啊!!!開始忘了,程序始終有問題- -!!
	Linksequeue_SetNull(q);
	ch = getchar();

	while(ch != '#')
	{
		Linksequeue_In(q, ch);			//入隊
		ch = getchar();
	}
	return q;
}

//取得頭結點
char Linksequeue_GetFront(linksequeue *q)
{
	if(Linksequeue_Empty(q))		//先判斷鏈隊列是否爲空
		return '\0';
	else
		return q->front->next->data;
}

//入隊
void Linksequeue_In(linksequeue *q, char dat)
{
	q->rear->next = (linklist*)malloc(sizeof(linklist));	
	q->rear = q->rear->next;		//尾結點移動
	q->rear->data = dat;			
	q->rear->next = NULL;			//尾結點爲空
}

//出隊
char Linksequeue_Out(linksequeue *q)
{
	linklist *s;

	if(Linksequeue_Empty(q))			//先要判斷隊列是否爲空
		return 0;
	else
	{
		s = q->front;					//頭結點移動到頭結點的下一個節點
		q->front = s->next;
		free(s);
		return q->front->data;
	}
}

//輸出顯示隊列
void ShowLinksequeue(linksequeue *q)
{
	linklist *s;
	
	s = q->front->next;
	while(s != NULL)
	{
		putchar(s->data);
		putchar(' ');
		s = s->next;
	}
	printf("\n");
}
其中讓我糾結的就是建立鏈隊列中的一句關於空間申請的語句q = (linksequeue*)malloc(sizeof(linksequeue));開始沒有這條語句時,程序就不執行while(1)裏面的語句了。運行程序輸入一串字符後,提示命令結束。開始百思不得其解,不知道爲何,後來靈感莫名以來,感受是沒有申請空間的問題,而後加上這條語句後果真正確。至於其中真正緣由,目前還不知道,有知道的高手若是看見這片文章的話,望解答個人疑惑。讓我知其因此然。
相關文章
相關標籤/搜索