數據結構學習(九)——鏈棧的操做

堆棧也能夠採用鏈式存儲結構,稱爲鏈棧。鏈棧常採用單鏈表表示。其實現是將鏈表的表頭做爲棧頂實現,這樣就不須要在單鏈表中增長頭結點,棧頂指針就是鏈表的頭指針。node

下面的代碼實現了鏈棧的相關操做,其中有個錯誤關於重複申請堆空間讓我鬱悶了會兒,不事後來找出來了。函數

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

typedef struct node
{
	char data;
	struct node *next;
}linkstack;

linkstack * Linkstack_Create();						//建立鏈棧
char Linkstack_GetTop(linkstack *q);				//取得棧頂
linkstack *Linkstack_In(linkstack *q, char dat);	//入棧
linkstack * Linkstack_Out(linkstack *q, char *dat);	//出棧
void Linkstack_SetNull(linkstack *q);				//置空棧
int	Linkstack_Empty(linkstack *q);					//棧是否爲空
void ShowLinkstack(linkstack *q);					//輸出顯示棧

int main(void)
{
	linkstack *q;
	int choice, ans;
	char dat;

	printf("鏈棧的操做練習:\n");
	printf("請依次輸入鏈棧字符數據('#'號表示結束):\n");
	q = Linkstack_Create();
	getchar();
	while(1)
	{
		printf("鏈棧操做:\n");
		printf("1.取得棧頂結點\n");
		printf("2.入棧\n");
		printf("3.出棧\n");
		printf("4.輸出顯示鏈棧\n");
		printf("5.退出程序\n");
		printf("作出選擇:");
		scanf("%d", &choice);
		getchar();				//消除回車爲後面帶來的影響
		switch(choice)
		{
		case 1:
			dat = Linkstack_GetTop(q);	
			if(dat == '\0')
				printf("取得頭結點失敗!\n");
			else
				printf("頭結點爲%c\n", dat);
			break;
		case 2:
			printf("輸入想入棧的字符:\n");
			dat = getchar();
			q = Linkstack_In(q, dat);
			break;
		case 3:
			q = Linkstack_Out(q, &dat);
			if(dat != '\0')
				printf("出棧的字符爲%c\n", dat);
			break;
		case 4:
			printf("輸出的字符依次爲:\n");
			ShowLinkstack(q);
			break;
		case 5:
			return 0;
			break;
		default:
			printf("選擇無效!\n");
			break;
		}
	}
	return 1;
}

//鏈棧置空
void Linkstack_SetNull(linkstack *q)
{
	linkstack *s;

	while(q != NULL)		//鏈棧置空時須要釋放每一個結點的空間
	{
		s = q;
		q = q->next;
		free(s);
	}
}

//判斷鏈棧是否爲空
int Linkstack_Empty(linkstack *q)
{
	if(q == NULL)
		return 1;
	else
		return 0;
}

//建立鏈棧
linkstack * Linkstack_Create()
{
	linkstack *q = NULL;
	char ch;

	Linkstack_SetNull(q);
	ch = getchar();

	while(ch != '#')
	{
	//	q = (linkstack*)malloc(sizeof(linkstack));
	//此句又讓人糾結了很久,有此句時建立的鏈棧只有棧頂字符,申請了兩次空間(下面入棧函數中一次),至於爲何會形成這種結果,暫時不知道- -!!
		q = Linkstack_In(q, ch);
		ch = getchar();
	}
	return q;
}

//取得棧頂結點
char Linkstack_GetTop(linkstack *q)
{
	if(Linkstack_Empty(q))			//先要判斷棧頂是否爲空
		return '\0';
	else
		return q->data;
}

//入棧,返回棧頂結點指針
linkstack *Linkstack_In(linkstack *q, char dat)
{
	linkstack *e;

	e = (linkstack*)malloc(sizeof(linkstack));
	e->data = dat;
	e->next = q;

	return e;
}

//出棧,返回棧頂結點指針
linkstack *Linkstack_Out(linkstack *q, char *dat)
{
	linkstack *s;

	if(Linkstack_Empty(q))					//先要判斷棧頂是否爲空
	{	
		*dat = '\0';
		return NULL;
	}
	else
	{
		*dat = q->data;
		s = q;
		q = q->next;
		free(s);
		return q;
	}
}

//輸出顯示鏈棧,從棧頂到棧底
void ShowLinkstack(linkstack *q)
{
	linkstack *s;

	s = q;					
	while(s != NULL)
	{
		putchar(s->data);
		putchar(' ');
		s = s->next;
	}
	printf("\n");
}
相關文章
相關標籤/搜索