數據結構:Stack
Stack設計與實現
Stack基本概念
棧是一種 特殊的線性表
棧僅能在線性表的一端進行操作
棧頂(Top):允許操作的一端
棧底(Bottom):不允許操作的一端
Stack的常用操作
創建棧
銷毀棧
清空棧
進棧
出棧
獲取棧頂元素
獲取棧的大小
C語言描述=====》棧的設計與實現 人生財富庫積累 |
#ifndef _MY_STACK_H_ #define _MY_STACK_H_
typedef void Stack;
Stack* Stack_Create();
void Stack_Destroy(Stack* stack);
void
int Stack_Push(Stack* stack, void* item);
void* Stack_Pop(Stack* stack);
void* Stack_Top(Stack* stack);
int Stack_Size(Stack* stack);
#endif //_MY_STACK_H_ |
棧的順序存儲設計與實現
1、基本概念
2、設計與實現
頭文件 |
#ifndef __MY_SEQLIST_H__ #define __MY_SEQLIST_H__
typedef void SeqList; typedef void SeqListNode;
SeqList* SeqStack_Create(int capacity);
void SeqStack _Destroy(SeqStack * list);
void SeqStack _Clear(SeqStack * list);
int SeqStack _Length(SeqStack * list);
int SeqStack _Capacity(SeqStack * list);
int SeqStack _Insert(SeqStack * list, SeqListNode* node, int pos);
SeqListNode* SeqList_Get(SeqList* list, int pos);
SeqListNode* SeqList_Delete(SeqList* list, int pos);
#endif //__MY_SEQLIST_H__ |
棧的鏈式存儲設計與實現
1、基本概念
2、設計與實現
頭文件 |
#ifndef _MY_LINKSTACK_H_ #define _MY_LINKSTACK_H_
typedef void LinkStack;
LinkStack* LinkStack_Create();
void LinkStack_Destroy(LinkStack* stack);
void LinkStack_Clear(LinkStack* stack);
int LinkStack_Push(LinkStack* stack, void* item);
void* LinkStack_Pop(LinkStack* stack);
void* LinkStack_Top(LinkStack* stack);
int LinkStack_Size(LinkStack* stack);
#endif //_MY_LINKSTACK_H_ |
棧的應用
應用1:就近匹配 |
幾乎所有的編譯器都具有檢測括號是否匹配的能力 如何實現編譯器中的符號成對檢測? #include <stdio.h> int main() { int a[4][4]; int (*p)[4]; p = a[0]; return 0; |
算法思路 從第一個字符開始掃描 當遇見普通字符時忽略,當遇見左符號時壓入棧中 當遇見右符號時從棧中彈出棧頂符號,並進行匹配 匹配成功:繼續讀入下一個字符 匹配失敗:立即停止,並報錯 結束: 成功: 所有字符掃描完畢,且棧為空 失敗:匹配失敗或所有字符掃描完畢但棧非空 |
當需要檢測成對出現但又互不相鄰的事物時 可以使用棧"後進先出"的特性 棧非常適合於需要"就近匹配"的場合 |
計算機的本質工作就是做數學運算,那計算機可以讀入字符串 "9 + (3 - 1) * 5 + 8 / 2"並計算值嗎? |
應用2:中綴 後綴 |
計算機的本質工作就是做數學運算,那計算機可以讀入字符串 "9 + (3 - 1) * 5 + 8 / 2"並計算值嗎? |
後綴表達式 ==?符合計算機運算 波蘭科學家在20世紀50年代提出了一種將運算符放在數字後面的後綴表達式對應的, 我們習慣的數學表達式叫做中綴表達式===》符合人類思考習慣 |
實例: 5 + 4=> 5 4 + 1 + 2 * 3 => 1 2 3 * + 8 + ( 3 – 1 ) * 5 => 8 3 1 – 5 * + |
中綴表達式符合人類的閱讀和思維習慣 後綴表達式符合計算機的"運算習慣" 如何將中綴表達式轉換成後綴表達式? |
中綴轉後綴算法: |
遍歷中綴表達式中的數字和符號 對於數字:直接輸出 對於符號: 左括號:進棧 運算符號:與棧頂符號進行優先級比較 若棧頂符號優先級低:此符合進棧 (默認棧頂若是左括號,左括號優先級最低) 若棧頂符號優先級不低:將棧頂符號彈出並輸出,之後進棧 右括號:將棧頂符號彈出並輸出,直到匹配左括號 遍歷結束:將棧中的所有符號彈出並輸出 中綴轉後綴 |
計算機是如何基於後綴表達式計算的? 8 3 1 – 5 * + |
遍歷後綴表達式中的數字和符號 對於數字:進棧 對於符號: 從棧中彈出右操作數 從棧中彈出左操作數 根據符號進行運算 將運算結果壓入棧中 遍歷結束:棧中的唯一數字為計算結果 |
棧的神奇! 中綴表達式是人習慣的表達方式 後綴表達式是計算機喜歡的表達方式 通過棧可以方便的將中綴形式變換為後綴形式 中綴表達式的計算過程類似程序編譯運行的過程 |
擴展:給你一個字符串,計算結果 "1+2*(66/(2*3)+7)" 1 字符串解析 詞法語法分析 優先級分析 數據結構選型===》棧還是樹? |
數據結構:Stack