資料結構筆記-棧的應用

在寫了發表於2020-10-04

棧的應用

  • 樹制轉換 鏈棧
  • 表示式求值
void Convertion(int n,in j)
{
// 將十進位制的 n 轉換為 j 進位制
	LinkStack s;
	int x;
	s.top = NULL;

	do{
			x = n % j;
			n = n / j;
			Push(s,x);
		}while(n)		// n == 0 迴圈結束
		
while(Pop(s,x))	court<<x<<endl;
}

表示式求值

  • 中綴表示式,字首表示式,字尾表示式

中綴表示式:(平常的數學式子) 運算子在兩運算數的中間

字首表示式(波蘭表示式):運算子號在兩運算元的前面;
運算順序:對字首式 從右向左掃描

字尾表示式(逆波蘭表示式):將運算子放兩運算元後;
運算順序:對字尾式 從左到右(比較符合平時的運算習慣)

  • 中綴表示式轉換為字尾表示式或字首表示式
    目的:方便計算機運算
  • 手動轉換(中綴轉字首;中綴轉字尾)
步驟:
step1: 加括號
step2:提運算子(字首提前面;字尾提後面)
		a+b		+ab		ab+

在這裡插入圖片描述

字首表示式(波蘭表示式)

  • 在字首表示式不存在運算子的優先順序問題,計算順序按照運算子出現的先後次序進行
  • 計算時會,從右向左掃描字首式
  • 掃描到運算子就把棧頂兩個運算元進行計算,結果進棧,直至表示式運算完

字尾表示式(逆波蘭表示式)

  • 計算順序完全按照 運算子出現的先後次序進行
  • 從左向右掃描字尾式
  • 掃描到運算子就取棧頂兩元素進行相應的運算,結果入棧,直至表示式算完

演算法 中綴轉字尾

從左向右		掃描中綴表示式
<a>掃描的是	運算元:直接輸出
<b>掃描的是	運算子:入棧,左括號“(”也入棧
	<1>	if	掃描的是	右括號)	,則彈出pop直至遇到棧中的左括號(	左括號只彈出不輸出
	<2> if 	棧頂的運算子優先順序 > 掃描的運算子的優先順序,一直彈出,直至棧頂運算子的優先順序 <	掃描運算子優先順序,再將掃描運算子入棧
<c> if	輸入結束,將棧中剩餘運算子依次彈出
void Change(SqStack *s,Elemtype str[])
{
	int i = 0;
	Elemtype e;
	InitStack(s);
	
	while(str[i] != \0')
	{
		// 直接輸出數字字元	掃描到運算子則 輸出空格結束迴圈
		while(isdigit(str[i]))
		{ 
			printf("%c",str[i++]);
			if(!isdigit(str[i]))	printf(" ");
		}
		
		// +號和-號優先順序是最低的【‘(’優先順序更低】
		//根據 棧頂元素優先順序 > 掃描元素優先順序,則一直彈出直至棧頂元素優先順序 小於掃描的優先順序
		//可知,棧空時+-入棧  或者  棧頂元素為 左括號( 入棧
		//其他情況則一直出棧,直至棧空或者遇到左括號(
		//彈出完了	再將掃描的運算子	入棧
		
		if(str[i] == '+' || str[i] == '-')
		{
			if(SEmpty(s))		push(s,str[i]);
			else
			{
				do
				{
					pop(s,&e);
					if(e == '(' )		push(s,e);
					else		printf("%c",e)	
				}while(!Sempty && e != '(');
				push(s,str[i]);
			}
		}
	//掃描的是右括號	則一直彈出	直至遇到左括號
	//左括號只彈出	不輸出
	else if(  str[i] == ')'  )
	{
		pop(s,&e);
		while(e != '(')
		{
			printf("%c",e);
			pop(s,&e);
		}
	}
//*號/號優先順序最高直接入棧;左括號直接入棧
	else if(str[i] == '*' || str[i] == '/' || str[i] == '(' )		push(s,str[i]);
	else if(str[i]  == '\0')	break;
	else	{printf("input is not valid");	return ;}
	i++;
}
//最後表示式若掃描結束,則將棧內剩餘的 運算子輸出
while(!SEmpty)
{
	pop(s,&e);
	printf("%c",e);
}

}

演算法-字尾表示式求值

<a>從左向右	掃描字尾表示式【掃描字串-】
<b>
	掃描的是運算元:則直接入棧
	掃描的是運算子:則取棧頂兩元素,進行相應計算,結果入棧
例子:pop(s,&e);b = e;pop(s,&e);a = e; a +-*/ b = c; push(s,c);
當取兩運算元運算時,第一個棧頂元素為運算元,第二個棧頂元素為被運算元(關係類同與除數與被除數)
	直至字尾表示式掃描完畢

相關文章