国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

做網(wǎng)站獨(dú)立云服務(wù)器什么意思網(wǎng)址大全瀏覽器

做網(wǎng)站獨(dú)立云服務(wù)器什么意思,網(wǎng)址大全瀏覽器,鄭州做網(wǎng)站推廣地,WordPress文章相冊插件本節(jié)講完棧下次再講一下隊列,最后補(bǔ)充一個串,我們的線性結(jié)構(gòu)基本就完事了。下圖中黃色框框圈中的是我們今日份內(nèi)容(分為兩篇博客): 知識體系圖 棧(Stack-LIFO)結(jié)構(gòu) 棧的基礎(chǔ)概念 棧(Stack)是一個后進(jìn)先出(Last-In-First-Out)的一個特殊數(shù)據(jù)…

?本節(jié)講完棧下次再講一下隊列,最后補(bǔ)充一個串,我們的線性結(jié)構(gòu)基本就完事了。下圖中黃色框框圈中的是我們今日份內(nèi)容(分為兩篇博客):

知識體系圖

棧(Stack-LIFO)結(jié)構(gòu)

棧的基礎(chǔ)概念

棧(Stack)是一個后進(jìn)先出(Last-In-First-Out)的一個特殊數(shù)據(jù)結(jié)構(gòu),只有一端可以操作,三面環(huán)墻。按照存儲方式可以分為順序存儲的棧和鏈?zhǔn)酱鎯Φ臈?即順序棧和鏈棧),另外還有一些特殊的棧需要我們了解:單調(diào)棧、共享棧。

不管什么棧,它的基本API接口(基本操作)都是:入棧(Push),出棧(Pop),查看棧頂元素(Top/Peek),判斷棧是否為空(isEmpty)。

棧頂(top):處于可以插入或刪除元素的一端,棧頂指針指向非空元素的下一個位置

棧底(base):處于不能插入或刪除元素的另一端,棧底指針固定指向。

空棧(empty):棧內(nèi)不包含任意元素,棧頂指針與棧底指針指向同一位置。

順序棧

采用順序結(jié)構(gòu)存儲的棧稱為順序棧,它的底層是數(shù)組,使用的是一段地址連續(xù)的空間。另外找一個尾指針充當(dāng)棧頂指針,指向棧頂元素的位置的下一個地址。判斷棧為空的條件就是棧頂指針指向棧底。

1.棧的順序存儲

站的順序存儲結(jié)構(gòu)可以定義為:一個棧底指針,一個棧頂指針

#define INIT_MAX_SIZE 20 //初始化棧時給的最大容量
typedef int DataType;//DataType的類型不確定,根據(jù)習(xí)慣初始假定為int
typedef struct{DataType* base;DataType* top;
}SqStack;

?2.棧的基本操作

初始化

初始化時,使用預(yù)先設(shè)置好的初值來開辟大小,并且初始一定是空棧,所以讓棧頂指針指向棧底即可。

void initStack(SqStack* s)
{s->base = (DataType*)malloc(sizeof(DataType)*INIT_MAX_SIZE);s->top = s->base;
}

判空

如果棧頂指針與棧底指針指向同一塊空間,那么棧就是空的,直接返回。這里傳不傳指針都可以,不需要進(jìn)行修改的操作,只進(jìn)行判斷,所以利用值傳遞也能實(shí)現(xiàn)目的

#include <stdbool.h>
bool isEmpty(SqStack s){return s.base == s.top;
}
bool isEmpty(SqStack* s){return s->base == s->top;
}

進(jìn)棧?

進(jìn)棧之前,我們先判斷棧是否為滿,如果滿棧,我們不能隨便加入,需要擴(kuò)容,我們選擇二倍擴(kuò)容的方式,如果擴(kuò)容失敗,結(jié)束程序,一旦我們擴(kuò)容成功,我們原來的棧頂指針也會失效,使用棧底指針加上原來的滿棧數(shù),跨越總步長回到棧頂?shù)南鄬ξ恢?。然后將棧頂設(shè)置為元素e,并自動跨越一個步長(++)。

/*插入元素e為新的棧頂元素*/
void Push(SqStack *s, DataType e){//滿棧if(s->top == s->base + INIT_MAX_SIZE){int size = INIT_MAX_SIZE*2;s->base = (DataType*)realloc(s->base,sizeof(DataType)*size);assert(s->base);s->top = s->base + size/2;}*(s->top) = e;    //將新插入元素賦值給棧頂空間s->top++; //更改棧頂指針//可以合并為*(s->top++)=e;
}

出棧

出棧就是要后面的元素?zé)o法訪問,那么只需要將棧頂指針縮減一個步長(--)即可,但在此之前,我們需要判斷是不是空棧,如果是空棧,我們就沒必要去進(jìn)行出棧的操作了。

/*若棧不空,則刪除S的棧頂元素*/
void Pop(SqStack *s){if(s->top == s->base){return;}S->top--;   //棧頂指針減1
}

?獲取棧頂元素

獲取棧頂元素,我們需要獲取的棧頂指針上一個位置內(nèi)存儲的內(nèi)容,所以我們進(jìn)行完判空操作后,我們需要對s->top-1進(jìn)行解引用(即取*)的操作。

/*讀棧頂元素*/
DataType Top(SqStack s){if(s->top == s->base){   //??誶eturn -1;}return *(s->top-1);   //返回棧頂元素
}

銷毀棧?

void destory(SqStack* s){if(s->base){free(s->base);s->top=s->base=NULL;}
}

3.單調(diào)棧專題

從名字上我們就可以看出來,單調(diào)棧中存放的數(shù)據(jù)應(yīng)該是有序的,所以單調(diào)棧本身也應(yīng)該分為單調(diào)遞增棧和單調(diào)遞減棧。單調(diào)的方向是從棧底到棧頂。

在進(jìn)行單調(diào)棧的講解時,我們會使用到上述的一些基本操作。我們來看一下單調(diào)棧的入棧過程:

typedef int DataType;//此處選取int作為示例for (遍歷這個數(shù)組)
{if (???|| 棧頂元素大于等于當(dāng)前比較元素){入棧;}else{while (棧不為空 && 棧頂元素小于當(dāng)前元素){棧頂元素出棧;更新結(jié)果;}當(dāng)前數(shù)據(jù)入棧;}
}

真題演練

?柱狀圖中的最大矩形

思路:當(dāng)前的數(shù)字可以向兩邊拓展,遇到比自己大的就接著拓展,小的就停止,然后用自己的高度乘以拓展的寬度,每次都更新最大面積,時間復(fù)雜度同樣為O(N^2),所以我們接著借助單調(diào)棧

這里我們通過這道例題來使用一下單調(diào)遞減棧

1.設(shè)置一個單調(diào)遞減的棧(棧內(nèi)0~n為單調(diào)遞增)
2.當(dāng)遇到小于棧頂元素的值,我們開始更新數(shù)據(jù),因?yàn)橛锌赡茏畲竺娣e就會出現(xiàn)在棧中的序列里
3.牢記棧中數(shù)據(jù)永遠(yuǎn)是有序的,這個問題比較復(fù)雜,所以讀者不妨對照著代碼來理解問題

int largestRectangleArea(vector<int>& heights) {heights.push_back(-1);/同理,我們希望棧中所有數(shù)據(jù)出棧,所以給數(shù)組最后添加一個負(fù)數(shù)SqStack st; initStack(&st);int ret = 0, top;for (int i = 0; i < heights.size(); i++){if (isEmpty(st) || heights[Top(st)] <= heights[i]){Push(&st,i);}else{while (!isEmpty(st) && heights[Top(st)] > heights[i]){top = Top(st);Pop(&st);//i-top指的是當(dāng)前矩形的寬度,heights[top]就是當(dāng)前的高度//再次強(qiáng)調(diào)棧中現(xiàn)在為單調(diào)遞增int tmp = (i - top)*heights[top];if (tmp > ret)ret = tmp;}Push(top);heights[top] = heights[i];}}return ret;
}

?4.共享棧專題

?利用棧底位置相對不變的特征,可讓兩個順序棧共享一個一維數(shù)組空間,將兩個棧的棧底分別設(shè)置在共享空間的兩端,兩個棧頂向共享空間的中間延伸,如下圖所示:

兩個棧共享同一片存儲空間,這片存儲空間不單獨(dú)屬于任何一個棧,某個棧需要的多一點(diǎn),它就可能得到更多的存儲空間;兩個棧的棧底在這片存儲空間的兩端,當(dāng)元素入棧時,兩個棧的棧頂指針相向而行。此時我們采取另外一種實(shí)現(xiàn)棧的方法,不使用真正的指針,使用下標(biāo)索引模擬兩個棧頂指針。定義方法如下:

 #define SharedStackMax 100typedef char SharedStackType;typedef struct{SharedStackType data[SharedStackMax];size_t top1;size_t top2;}SharedStack;

共享棧的基本操作方法:?

 void SharedStackInit(SharedStack*stack){if(stack==NULL){return;}stack->top1=0;stack->top2=SharedStackMax;}void SharedStackPush1(SharedStack*stack,SharedStackType value){if(stack->top1==stack->top2||stack==NULL){return;}stack->data[stack->top1++]=value;return;}void SharedStackPush2(SharedStack*stack,SharedStackType value){if(stack->top2==stack->top1||stack==NULL){return;}                                                                       stack->data[--stack->top2]=value;}int  SharedStackTop1(SharedStack*stack,SharedStackType*value){if(stack==NULL||value==NULL){return 0;}if(stack->top1==0){return 0;}*value=stack->data[top1-1];return 1;}int SharedStackTop2(SharedStack*stack,SharedStackType*value){if(stack==NULL||value==NULL){return 0;}if(stack->top2==SharedStackMax){return 0;}*value=stack->data[stack->top2];return 1;
}void SharedStackPop1(SharedStack*stack){if(stack==NULL || stack->top1==0){return;}stack->top1--;}void SharedStackPop2(SharedStack*stack){if(stack->top2==SharedStackMax || stack==NULL){return;}stack->top2++;}     

鏈棧?

1.棧的鏈?zhǔn)酱鎯?/h4>

采用鏈?zhǔn)酱鎯Φ臈7Q為鏈棧,鏈棧的優(yōu)點(diǎn)是便于多個棧共享存儲空間和提高其效率,且不存在棧滿上溢的情況,我們就省去了不斷擴(kuò)容的麻煩。通常采用不帶頭結(jié)點(diǎn)的單鏈表實(shí)現(xiàn),而且為了方便,使用頭插法頭刪法更簡單,所以我們的入棧和出棧就是單鏈表的頭插和頭刪的操作。Lhead指向棧頂元素,鏈棧的結(jié)構(gòu)圖如下所示:

對于鏈棧來說,空棧的概念即是Lhead指向NULL的時候。?

/*構(gòu)造節(jié)點(diǎn)*/
typedef struct StackNode{ElemType data;struct StackNode *next;
}StackNode, *LinkStackPrt;
//將StackNode* 重命名為LinkStackPrt的好處是避免下面操作出現(xiàn)二級指針的形式。(實(shí)質(zhì)還是二級指針)/*構(gòu)造鏈棧*/
typedef struct LinkStack{LinkStackPrt top;int count;
}LinkStack;

2.鏈棧的基本操作

鏈棧的進(jìn)棧

對于鏈棧的進(jìn)棧push操作,我們會創(chuàng)建一個棧節(jié)點(diǎn),然后進(jìn)行鏈表的頭插操作。

void Push(LinkStack *S, ElemType e){LinkStackPrt p = (LinkStackPrt)malloc(sizeof(StackNode));p->data = e;p->next = S->top;    //把當(dāng)前的棧頂元素賦值給新節(jié)點(diǎn)的直接后繼S->top = p; //將新的結(jié)點(diǎn)S賦值給棧頂指針S->count++;
}

鏈棧的出棧

無需多說,頭刪即可

Element Pop(LinkStack *S){if(StackEmpty(*S)){return -1;}Element e = S->top->data;//臨時存儲棧頂元素LinkStackPtr p;p = S->top; //將棧頂結(jié)點(diǎn)賦值給pS->top = S->top->next;  //使得棧頂指針下移一位,指向后一結(jié)點(diǎn)free(p);    //釋放結(jié)點(diǎn)pS->count--;return e;
}

棧的算法應(yīng)用

遞歸專題

我們將遞歸時就提到過,遞歸是函數(shù)的遞進(jìn)調(diào)用與返回,而函數(shù)的調(diào)用與銷毀又是以棧的形式進(jìn)行的。所以能用棧解決的問題一定可以用遞歸解決。而能用遞歸的方式解決的問題,棧不一定能解決,但一定依托于棧的形式結(jié)構(gòu)。因?yàn)閷τ跅=Y(jié)構(gòu)本身來講是作為一個容器來用的,遞歸才是存儲一系列操作這種非數(shù)據(jù)類型的特殊棧結(jié)構(gòu)。

基礎(chǔ)算法--遞歸算法【難點(diǎn)、重點(diǎn)】-CSDN博客

調(diào)用堆棧:每次遞歸調(diào)用時,棧上會創(chuàng)建一個新的堆棧幀,用于存儲該調(diào)用的上下文。

空間復(fù)雜度:遞歸的深度可能導(dǎo)致棧溢出,尤其在遞歸深度較大而沒有適當(dāng)?shù)幕厩闆r時。

迭代替代:有些遞歸算法可以用顯式?;蜓h(huán)來實(shí)現(xiàn),從而避免遞歸帶來的棧溢出問題。

四則運(yùn)算表達(dá)式專題

四則運(yùn)算在這里的應(yīng)用其實(shí)包括后綴表達(dá)式和前綴表達(dá)式,以及我們平常熟悉的中綴表達(dá)式。

綴所處的位置不同代表的含義是四則運(yùn)算符所處的位置不同。例如:

a+b*(c/d+2):中綴表達(dá)式

* + a b c:前綴表達(dá)式( ==(a+b)*c )

a b c d - * + e f / -:后綴表達(dá)式( ==a+b*(c-d)-e/f )

四則運(yùn)算表達(dá)式的專題我們以一道例題作為訓(xùn)練:逆波蘭表達(dá)式(前綴表達(dá)式)。

逆波蘭表達(dá)式是一種把運(yùn)算符前置的算術(shù)表達(dá)式,例如普通的表達(dá)式2 + 3的逆波蘭表示法為+ 2 3。逆波蘭表達(dá)式的優(yōu)點(diǎn)是運(yùn)算符之間不必有優(yōu)先級關(guān)系,也不必用括號改變運(yùn)算次序,例如(2 + 3) * 4的逆波蘭表示法為* + 2 3 4。本題求解逆波蘭表達(dá)式的值,其中運(yùn)算符包括+ - * /四個。

對于原逆波蘭表達(dá)式:- + * - c d b a? / e f

當(dāng)我們遇到符號時,將其入棧,等到下面兩個是數(shù)字時再出棧,如果遇到數(shù)字,直接讓其入棧,然后出棧。我們對下面的圖進(jìn)行詳細(xì)的步驟分析:

?

文字配合圖片食用效果更甚哦:

下面給出代碼:?

#include <bits/stdc++.h>
using namespace std;/*逆波蘭表達(dá)式*/
string st = "+-*/";
double calc() {string str; cin >> str;switch (str[0]) {case '+':return calc() + calc();case '-':return calc() - calc();case '*':return calc() * calc();case '/':return calc() / calc();default:return stod(str);}
}
signed main() {printf("%f\n", calc());return 0;
}

感謝大家觀看!多多支持哦!

http://aloenet.com.cn/news/46185.html

相關(guān)文章:

  • 網(wǎng)站建設(shè)平臺漢龍網(wǎng)頁制作官方網(wǎng)站
  • 自己做的個人網(wǎng)站無法備案廣東東莞今日最新消息
  • 新手學(xué)做網(wǎng)站必備軟件seo技術(shù)培訓(xùn)課程
  • 網(wǎng)站支付功能怎么做全自動推廣引流軟件免費(fèi)
  • 日本做暖網(wǎng)站推廣網(wǎng)站要注意什么
  • 寧德住房和城鄉(xiāng)建設(shè)部網(wǎng)站怎樣做網(wǎng)絡(luò)推廣營銷
  • 新網(wǎng)站怎么做權(quán)重國際新聞軍事最新消息
  • 廣東網(wǎng)站制作百度客服人工電話24小時
  • 拼多多網(wǎng)站分析百度網(wǎng)站登錄
  • 做類似交易貓的網(wǎng)站如何優(yōu)化網(wǎng)頁
  • 六安網(wǎng)站建設(shè)哪家靠譜線下推廣宣傳方式有哪些
  • 網(wǎng)站眾籌該怎么做公眾號軟文是什么意思
  • 忍不住在樓道里面做免費(fèi)網(wǎng)站千萬不要學(xué)網(wǎng)絡(luò)營銷
  • 網(wǎng)站下方一般放什么原因宣傳推廣策略
  • 計算機(jī)專業(yè)里面哪個專業(yè)最好攀枝花seo
  • 營銷型網(wǎng)站一套東莞seo網(wǎng)站優(yōu)化排名
  • 哈爾濱住房和城鄉(xiāng)建設(shè)廳網(wǎng)站品牌推廣方案怎么寫
  • 鐵道部網(wǎng)上訂票網(wǎng)站素材網(wǎng)站分析案例
  • 家居飾品網(wǎng)站建設(shè)論文怎么在百度上推廣自己的產(chǎn)品
  • 動態(tài)網(wǎng)站與靜態(tài)網(wǎng)站的區(qū)別北京百度seo服務(wù)
  • 020模版網(wǎng)站制作網(wǎng)絡(luò)營銷的推廣方式
  • 51自學(xué)網(wǎng)官方網(wǎng)站百度廣告電話號碼
  • 各大網(wǎng)站做推廣的廣告怎么做做引流的公司是正規(guī)的嗎
  • 肇慶網(wǎng)站建設(shè)公司凡科小程序
  • 網(wǎng)站設(shè)計開發(fā)人員國家高新技術(shù)企業(yè)名單
  • 電影網(wǎng)站建設(shè)多少錢百度網(wǎng)站入口
  • 做網(wǎng)站排名費(fèi)用多少百度風(fēng)云榜明星
  • 手機(jī)網(wǎng)站有什么區(qū)別嗎廣告推廣平臺代理
  • 做公司網(wǎng)站的目的是什么網(wǎng)絡(luò)推廣運(yùn)營是做什么
  • 渭南公司做網(wǎng)站蘇州seo關(guān)鍵詞優(yōu)化價格