目錄3.1.2佇列的定義和特點
3.2案例引入
2、案例3.2:括號匹配的檢驗
3.案例3.3:表示式求值
4.案例3.4:舞伴問題
3.3棧的表示和操作的實現
棧是限定僅在表尾進行插入或者刪除操作的線性表。因此,對於棧來說,表尾端有其特殊含義,稱為棧頂,相應的,表頭端稱為棧底。不含元素的空表稱為空棧。
先進後出(filo)
順序棧和鏈式棧,實際上棧的本質是線性表,不過是加了操作限制
和棧類似都是操作受限制的線性表,只允許在一端進行插入(隊尾:rear),在一端進行刪除(隊頭:front);
先進先出(fifo)
順序隊和鏈式隊
當將乙個十進位制整數n轉換為八進位制數時,在計算過程中,把n與8求餘得到的八進位制數的各位依次進棧,計算完畢後將棧中的八進位制數依次出棧輸出,輸出結果就是待求得的八進位制數
void conversion(int n)
while(!stackempty(s)) //當棧為非空時,迴圈
snode, *linkstack;
status initstack(linkstack &s)
bool stackempty(linkstack s)
status push(linkstack &s, selemtype e)
p->data = e;
p->next = s;
s = p;
return ok;
}status pop(linkstack &s, selemtype &e)
status gettop(linkstack &s)
//演算法3.21 括號的匹配
status matching() //switch
cin >> ch; //繼續讀入下乙個字元
} //while
if (stackempty(s) && flag)
return true; //匹配成功
else
return false; //匹配失敗
}int main()
1、先定義、建立棧的操作(查、刪、插);
2、定義括號匹配演算法brack,初始化棧;
3、設定標記性變數flag來表決迴圈匹配結果,1表示匹配成功,0則不匹配;
4、掃瞄表示式,判斷是否符合匹配條件,是左括號就呼叫push壓入棧
任何乙個表示式都是由運算元(operand)運算子(operator)和界限符(delimiter)組成的,統稱它們為單詞。一般地,運算元既可以是常數,也可以是被說明為變數或常量的識別符號;運算子可以分為算術運算子、關係運算子和邏輯運算子 3 類;基本界限符 有左右括號和表示式結束符等。為了敘述的簡潔,在此僅討論簡單算術表示式的求值問題,這種表示式只含加、減、乘、除4種運算子。讀者不難將它推廣到更一般的表示式上。
char evaluateexpression ()
{//算術表示式求值的算符優先演算法,設optr和opnd分別為運算子棧和運算元棧
initstack(opnd); //初始化opnd棧
initstack(optr); //初始化optr棧
push (optr,'#') ; // 將表示式起始符"#" 壓人optr棧
cin>>ch;
while(ch!='#' | | gettop(optr) !='#' ) //表示式沒有掃瞄完畢或optr的棧頂元素不為"# "
//ch不是運算子則進opnd棧
else
switch (precede (gettop (optr) , ch)) //比較optr的棧頂元素和ch的 優先順序
//switch
}//while
return gettop (opnd) ; //opnd棧頂元素即為表示式求值結果
}
1.初始化optr棧和opnd棧,將表示式起始符「#」壓入optr棧。對千舞伴配對問題,先入隊的男士或女士先出隊配成舞伴,因此設定兩個佇列分別存放男士和女士入隊者。假設男士和女士的記錄存放在乙個陣列中作為輸入,然後依次掃瞄該陣列的各元素,並根據性別來決定是進入男隊還是女隊。 當這兩個佇列構造完成之後,依次將兩隊當前的隊頭元素出隊來配成舞伴,直至某佇列變空為止。 此時,若某隊仍有等待配對者,則輸出此佇列中排在隊頭的等待者的姓名,此人將是下一輪舞曲開始時第乙個可獲得舞伴的人。2.掃瞄表示式,讀人第乙個字元ch,如果表示式沒有掃瞄完畢至「#」或optr的棧頂元素不為「#」時,則迴圈執行以下操作:
若ch不是運算子,則壓入opnd棧,讀入下一字元ch;
若ch是運算子,則根據optr 的棧頂元素和ch的優先順序比較結果,做不同的處理:
若是小於,則ch 壓入optr棧,讀入下一字元ch;
若是大於,則彈出optr棧頂的運算子,從 opnd棧彈出兩個數,進行相應運算,結果壓入opnd棧;
若是等於,則optr 的棧頂元素是「(」且ch是「)」,這時彈出optr棧頂的「(」,相當於括號匹配成功,然後讀人下一字元ch。
3.opnd棧頂元素即為表示式求值結果,返回此元素。
void dancepartner(person dancer,int num)
{//結構陣列dancer中存放跳舞的男女,num是跳舞的人數。
initqueue(mdancers); //男士佇列初始化
initqueue(fdancers); //女士佇列初始化
for(i=0;i1.初始化 mdancers 佇列和 fdancers 佇列。
2.反覆迴圈,依次將跳舞者根據其性別插入 mdancers 佇列或 fdancers 佇列。
3.當 mdancers 佇列和 fdancers 佇列均為非空時, 反覆迴圈, 依次輸出男女舞伴的姓名。
4.如果 mdancers 隊列為空而 fdancers 佇列非空, 則輸出 fdancers 佇列的隊頭女士的姓名。
5.如果 fdancers 隊列為空而 mdancers 佇列非空, 則輸出 mdancers 佇列的隊頭男士的姓名。
棧的基本操作除了入棧和出棧外,還有棧的初始化,棧空長大判定,以及取棧頂元素等。下面給出棧的抽象資料型別定義
順序棧:利用一組位址連續的儲存單元依次存放自棧底到棧頂的資料元素,把陣列中下標為0的一端作為棧底,為了只是棧中元素的位置,我們定義變數top來指示棧頂元素在順序棧中的位置,top為整型.
public class sequencestack
public sequencestack(int n){}
//在棧頂插入乙個新元素
public void push(t obj){}
//刪除棧頂元素
public t pop(){}
//取出棧頂資料元素
public t gethead(){}
//判斷當前棧是否為空
public boolean isempty(){}
//求出棧中資料元素的個數
public int size(){}
//依次訪問棧中每個元素並輸出
public void nextorder(){}
//銷毀乙個已存在的棧
public void clear(){}
}
ps:1.top為指標,top指向棧頂元素的位置
top的初始值為-1,指向棧底,而這個top==-1也可作為棧空的標誌,每當插入乙個新的棧頂元素時,先把棧頂指標top增加1,再把入棧的元素放到top指標指向的位置。
刪除棧頂元素時,先刪除棧頂,再將棧頂指標top減去1。
非空棧中的棧頂指標top始終在棧頂元素的位置上。
public class sequencestack
public sequencestack(int n)
top=-1;
stackarray=(t)new object[n];
}
入棧時,首先應該判斷棧是否滿了,棧滿時,不能入棧,否則出現空間溢位,引起錯誤,這種現象稱為上溢。
public void push(t obj)
top=top-1;
return stackarray[top+1];
}
讀棧時,需要先判度棧是否為空,為空時,不能操作,否則產生錯誤。
//取出棧頂資料元素
public t gethead()
return stackarray[top];
第三章 棧和佇列
棧和佇列 一 棧 1 棧的定義 棧是限定僅在表尾進行插入和刪除操作的線性表,允許插入和刪除的一端稱為棧頂,另一端稱為棧底,不含任何資料元素的棧稱為空棧。2 在任何時候出棧的元素都只能是棧頂元素,即最後最後入棧者最先出棧。所以棧中元素除了具有線性關係外,還具有後進先出的特性。3 棧的抽象資料型別定義 ...
第三章 棧和佇列
棧和佇列是兩種常用的資料結構,同時又是操作受限的線性表,也是兩種重要的抽象資料型別。1 1棧是限定僅在表尾進行插入和刪除操作的線性表。棧中元素具有線性關係和後進先出的特性。2雖然對插入和刪除操作的位置限制減少了棧的靈活性,但同時也使得棧的操作更有效更容易實現。3棧的儲存結構分兩種,一種是順序儲存結構...
第三章 棧和佇列
第三章棧和佇列 一 棧1.棧 限定僅在表尾進行插入和刪除操作的線性表 允許插入和刪除的一端稱為棧頂 另一端稱為棧底 2.空棧 不含任何資料元素的棧。3.在任何時候出棧的元素都只能是棧頂元素,即最後入棧者最先出棧,具有後進先出的特性。4.棧的抽象資料型別定義 1 push 輸入 元素值 x 輸出 如果...