1. 程式人生 > >數據結構:Stack

數據結構:Stack

top 獲取 描述 turn 字符串 運算符 des gin 程序

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

Stack_Clear(Stack* stack);

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