1. 程式人生 > >(鏈)棧的基本操作 C++

(鏈)棧的基本操作 C++

#include "iostream"

using namespace std;

//=====================棧(後進先出)====================
/*棧也是線性表,限定在棧頂進行插入&刪除,時間複雜度均為O(1)
棧:最大儲存大小+資料*/

//=================棧的順序儲存==================
const int MAXSIZE = 20;

//棧的資料結構:
struct Sqstack
{
	int data[20];
	int top;
	Sqstack(int x) :top(x){};
};

/*棧的遍歷:*/
bool StackVisit(const Sqstack *S)
{
	if (S->top == -1)
		return false;
	else
	{
		for (int i = 0; i <= S->top; i++)
			cout << S->data[i] << " ";
		cout << endl;
		return true;
	}
}



/*進棧操作push:
1.棧頂指標 S->top 先自增1,給需要進棧的元素騰出記憶體空間。
2.再賦值。就是給對應的陣列元素賦值:S->data[S->top]=e
*/
bool myPush(Sqstack *S, int elem)
{
	if (S->top == MAXSIZE - 1)
	{
		cout << "棧已滿!" << endl;
		return false;
	}
	else
	{
		S->top++;
		S->data[S->top] = elem;
		return true;
	}
}

/*出棧操作pop:
先把要出棧的元素獲取到,然後再指標自減,把空間釋放出來。
*/
bool MyPop(Sqstack *S)
{
	if (S->top == -1)
	{
		cout << "空棧!" << endl;
		return false;
	}
	else
	{
		S->top--;
		return true;
	}
}

/*獲取順序棧的棧頂元素:*/
bool GetTop(Sqstack *S, int &elem)
{
	if (S->top == -1)
	{
		cout << "空棧!" << endl;
		return false;
	}
	else
	{
		elem = S->data[S->top];
		return true;
	}
}

//判斷是否為空棧
bool StackEmpty(Sqstack *S)
{
	if (S->top == -1)
		return true;
	else
		return false;
}

//置空棧
bool ClearStack(Sqstack *S)
{
	S->top = -1;
	return true;
}

//兩棧共享空間

//=======================================


//=============棧的鏈式儲存============
/*鏈棧也是一種單鏈表,棧頂指標即為單鏈表頭指標,不需要頭結點,不存在慢棧情況。空棧即top==NULL
鏈棧:top指標+節點(資料)*/
struct StackNode  //鏈棧節點
{
	int val;
	StackNode *next;
	StackNode(int x) :val(x), next(NULL){};
};

typedef struct LinkStack //頭結點
{
	StackNode *top;
	int count;//記錄棧中元素個數
};

LinkStack* InitLinkStack()
{
	LinkStack *p = new LinkStack;
	p->count = 0;
	p->top = NULL;
	return p;
}

//鏈棧的進棧操作Push
/*1.處理新結點s的後繼,這個後繼就是原本的棧頂結點。
2.將棧頂指標 top 重新指向新結點s就行了。
*/
bool myLinkPush(LinkStack *S, int data)
{
	StackNode *p = new StackNode(data);
	p->next = S->top;
	S->top = p;
	S->count++;
	return true;
}

//鏈棧的出棧操作Pop:
/*1.首先設定一個工作結點 p,並且將棧頂結點賦值給它。
2.然後將棧頂指標下移一位,指向下一結點。程式碼表示為 S->top=S->top->next;
3.最後把結點 p delete掉,count--。*/
bool myLinkPop(LinkStack *S)
{
	if (S->top == NULL)
	{
		cout << "空棧!" << endl;
		return false;
	}
	else
	{
		StackNode *p = S->top;
		S->top = S->top->next;
		delete p;

		return true;
	}
}

//鏈棧的遍歷:
bool VisitLinkStack(LinkStack *S)
{
	if (S->top==NULL)
	{
		cout << "空棧!" << endl;
		return false;
	}
	else
	{
		StackNode *p = S->top;

		while (p != NULL)
		{
			cout << p->val << " ";
			p = p->next;
		}
		cout << endl;
		return true;
	}
}

//判斷鏈棧是否為空
bool LinkStackEmpty(LinkStack *S)
{
	if (S->count == 0)
		return true;
	else
		return false;
}

//鏈棧置空:方法是設定兩個工作結點,開始迴圈。在釋放p之前,讓q成為p的後繼。
bool ClearLinkStack(LinkStack *S)
{
	if (S->top == NULL)
		return true;
	else{
		StackNode *p, *q;
		p = S->top;
		while (p)
		{
			q = p;
			p = p->next;
			delete q;
		}
		S->count = 0;
		S->top = NULL;
		return true;
	}
}
//=============================================

//遞迴:定義必須至少有一個條件,滿足時遞迴不再進行,即不再引用自身而是返回值退出
//斐波那契的遞迴函式
int Fbi(int i)
{
	if (i < 2)
		return i == 0 ? 0 : 1;
	else
		return Fbi(i - 1) + Fbi(i - 2);
}

//將中綴表示式轉化為字尾表示式:
/*從左到右遍歷中綴表示式的每個數字和符號,若是數字就輸出,即成為字尾表示式的一部分;
若是符號,則判斷其與棧頂符號的優先順序,是右括號或優先順序低於找頂符號(乘除優先加減)則棧頂元素依次出找並輸出,
並將當前符號進棧,一直到最終輸出字尾表示式為止*/

int main()
{
	//==============棧的順序儲存===========
// 	Sqstack *S = new Sqstack(-1);
// 	int n = 0;
// 	while (cin >> n)
// 		myPush(S, n);
// 	
// 	MyPop(S);
// 	StackVisit(S);

	//============鏈棧===================
	LinkStack *S = InitLinkStack();
	int n;
	while (cin>>n)
		myLinkPush(S, n);

	//myLinkPop(S);
	ClearLinkStack(S);
	VisitLinkStack(S);



	system("pause");
	return 0;
}