<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
注意:
1、函數呼叫也有棧,這兩個棧有區別嗎?
當然有區別。函數呼叫會呼叫棧幀,記憶體裡頭也有一個棧,程式執行起來時要執行函數,函數裡頭的區域性變數、引數、返回值等等都要存在函數棧幀裡頭。
這兩個棧沒有任何關聯,一個是資料結構中的棧。另一個是作業系統中記憶體劃分的一個區域,叫做棧,用來函數呼叫時,建立棧幀。雖然本質上沒有任何關聯,但都符合後進先出的規則。
2、假設入棧順序為:1 2 3 4,那麼出棧順序一定為:4 3 2 1 嗎?
當然不是。雖說規則上明確後進先出,可這是相對而言的,如果說它每進一個再出一個,然後再繼續壓棧,那不同樣符合後進先出的規則嗎。就如同上例,你說它出棧順序為1 2 3 4 都不足為奇,每進一個出一個再進,同樣符合規則。類似的入棧兩個再出再進再出也是可以的,好比如2 1 4 3。
Stack.h 檔案:
//建立棧結構 typedef int STDataType; typedef struct Stack { STDataType* a; //儲存資料 int top; //棧頂的位置 int capacity; //容量 }ST;
思想:
初始化還是相對比較簡單的,學了之前的順序表,初始化棧就很輕鬆了
Stack.h 檔案:
//初始化棧 void StackInit(ST* ps);
Stack.c 檔案:
//初始化棧 void StackInit(ST* ps) { assert(ps); ps->a = NULL; ps->top = 0; ps->capacity = 0; }
注意:
這裡初始化的時候將top置為0是有意圖的。首先,由上文建立棧結構時已經標註了,top是用來記錄棧頂的位置,既然是棧頂的位置,那當top初始化為0時,我們可以直接將資料放入棧中,隨後top++,但是當top初始化為-1時,top首先要++才能放入資料,因為資料不可能在負數不屬於棧的位置上放入。下圖演示過程:
本文以 top = 0 範例
思想:
動態開闢的記憶體空間一定要釋放,free置空即可,並把其餘資料置0。
Stack.h 檔案:
//銷燬棧 void StackDestory(ST* ps);
Stack.c 檔案:
//銷燬棧 void StackDestory(ST* ps) { assert(ps); free(ps->a); ps->a = NULL; ps->capacity = ps->top = 0; }
思路:
前文已經強調了top初始化為0,那麼理應直接壓入資料,並把top++,不過在這之前,得判斷空間是否夠,當top=capacity的時候,棧就滿了,那麼就需要realloc擴容。
Stack.h 檔案:
//壓棧 void StackPush(ST* ps, STDataType x);
Stack.c 檔案:
//壓棧 void StackPush(ST* ps, STDataType x) { assert(ps); //如果棧滿了,考慮擴容 if (ps->top == ps->capacity) { int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; //檢測容量 ps->a = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType)); if (ps->a == NULL) { printf("realloc failn"); exit(-1); } ps->capacity = newcapacity; //更新容量 } ps->a[ps->top] = x;//將資料壓進去 ps->top++;//棧頂上移 }
思路:
在你出棧之前,要確保top不為空,而top不為空的條件就是top>0,所以還要斷言top>0,隨後,直接將棧頂位置下移--即可。跟順序表的思想大同小異。
Stack.h 檔案:
//出棧 void StackPop(ST* ps);
Stack.c 檔案:
//出棧 void StackPop(ST* ps) { assert(ps); assert(ps->top > 0); ps->top--; }
思路:
首先要搞清楚誰才是棧頂元素,是top位置還是top-1位置?很顯然是top-1的位置才是棧頂元素,因為在前文初始化的時候已經明確指出top為0,當時壓棧時直接放入資料的,此時第一個資料下標為0,隨後++top再壓入其它資料,由此可見,棧頂元素即下標top-1的位置。
Stack.h 檔案:
//存取棧頂資料 STDataType StackTop(ST* ps);
Stack.c 檔案:
//存取棧頂資料 STDataType StackTop(ST* ps) { assert(ps); assert(ps->top > 0); return ps->a[ps->top - 1]; //top-1的位置才為棧頂的元素 }
思想:
上文講到下標top-1才是棧頂元素,那麼是不是說總共就是top-1個元素呢?當然不是,這裡跟陣列下標一樣的思想,元素個數應該就是top個,直接返回即可。
Stack.h 檔案:
//有效元素個數 int StackSize(ST* ps);
Stack.c 檔案:
//有效元素個數 int StackSize(ST* ps) { assert(ps); return ps->top; }
思路:
當top的值為0時即為空,return直接返回即可
Stack.h 檔案:
//判空 bool StackEmpty(ST* ps);
Stack.c 檔案:
//判空 bool StackEmpty(ST* ps) { assert(ps); return ps->top == 0; //如果top為0,那麼就為真,即返回 }
Test.c 檔案:
void TestStack() { ST st; StackInit(&st); StackPush(&st, 1); StackPush(&st, 2); StackPush(&st, 3); StackPush(&st, 4); while (!StackEmpty(&st)) { printf("%d ", StackTop(&st)); StackPop(&st); } printf("n"); StackDestory(&st); }
效果如下:
#pragma once #include<stdio.h> #include<stdlib.h> #include<stdbool.h> #include<assert.h> //建立棧結構 typedef int STDataType; typedef struct Stack { STDataType* a; //儲存資料 int top; //棧頂的位置 int capacity; //容量 }ST; //初始化棧 void StackInit(ST* ps); //銷燬棧 void StackDestory(ST* ps); //壓棧 void StackPush(ST* ps, STDataType x); //出棧 void StackPop(ST* ps); //判空 bool StackEmpty(ST* ps); //存取棧頂資料 STDataType StackTop(ST* ps); //有效元素個數 int StackSize(ST* ps);
#define _CRT_SECURE_NO_WARNINGS 1 #include"Stack.h" //初始化棧 void StackInit(ST* ps) { assert(ps); ps->a = NULL; ps->top = 0; ps->capacity = 0; } //銷燬棧 void StackDestory(ST* ps) { assert(ps); free(ps->a); ps->a = NULL; ps->capacity = ps->top = 0; } //壓棧 void StackPush(ST* ps, STDataType x) { assert(ps); //如果棧滿了,考慮擴容 if (ps->top == ps->capacity) { int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; //檢測容量 ps->a = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType)); if (ps->a == NULL) { printf("realloc failn"); exit(-1); } ps->capacity = newcapacity; //更新容量 } ps->a[ps->top] = x;//將資料壓進去 ps->top++;//棧頂上移 } //出棧 void StackPop(ST* ps) { assert(ps); assert(ps->top > 0); ps->top--; } //判空 bool StackEmpty(ST* ps) { assert(ps); return ps->top == 0; //如果top為0,那麼就為真,即返回 } //存取棧頂資料 STDataType StackTop(ST* ps) { assert(ps); return ps->a[ps->top - 1]; //top-1的位置才為棧頂的元素 } //有效元素個數 int StackSize(ST* ps) { assert(ps); return ps->top; }
#define _CRT_SECURE_NO_WARNINGS 1 #include"Stack.h" void TestStack() { ST st; StackInit(&st); StackPush(&st, 1); StackPush(&st, 2); StackPush(&st, 3); StackPush(&st, 4); while (!StackEmpty(&st)) { printf("%d ", StackTop(&st)); StackPop(&st); } printf("n"); StackDestory(&st); } int main() { TestStack(); return 0; }
到此這篇關於C語言超詳細講解棧的實現及程式碼的文章就介紹到這了,更多相關C語言 棧的實現內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45