C語言中順序棧和鏈棧的定義和使用詳解
棧的基本內(nèi)容
無論是我們接下來要講的棧還是后面要講到的隊(duì)列,他們雖然在名字上不同于我們之前的順序表或者單鏈表,但是它們本質(zhì)也是線性表,只是在基本操作上沒有表那么“自由”。比如:棧只能從棧頂進(jìn)行插入和刪除,而隊(duì)列只能從對(duì)頭進(jìn)行刪除,隊(duì)尾進(jìn)行插入。
舉例:
疊放在一起的盤子,當(dāng)想要加入新的盤子時(shí),只能在底部或者尾部加入,刪除同樣也是。
空棧:
棧頂和棧底:
順序棧
既然上文都說到“棧”和“隊(duì)列”都是一種“特殊的”線性表”,那么順序棧,顧名思義就是按照順序存儲(chǔ)的棧。
定義
既然是順序存儲(chǔ)的,那么我們依然可以和順序表相類似,采用數(shù)組去存放!
typedef struct { int data[size]; int top;//棧頂指針 }seqstack;//seqstack為結(jié)構(gòu)體類型
入棧操作
對(duì)于順序表的插入操作,我們?cè)跅V薪凶?ldquo;入棧”,由于棧的特殊性,只能在棧頂進(jìn)行操作。
需要提醒的是:一定是棧頂指針先進(jìn)行移動(dòng),再將新插入的元素賦給棧頂空間。也就是說S.top = S.top + 1;S.data[S.top] = x;
的順序不能發(fā)生顛倒。
void Pushstack(seqstack& S) { if (S.top == size) printf("棧滿,拒絕元素繼續(xù)入棧!"); else { printf("請(qǐng)依次輸入你要入棧的元素:\n"); int x,i; for (i = 0; i < size; i++) { scanf("%d", &x); S.top = S.top + 1; S.data[S.top] = x; printf("入棧成功!\n"); } } }
舉例:
出棧
雖然是“出棧”,但是如果后續(xù)沒有入棧操作對(duì)出棧位置進(jìn)行數(shù)據(jù)覆蓋的話,其實(shí)出棧并不是真正意義上的“消失”,只是在邏輯上上被刪除了,其實(shí)給出下標(biāo)地址,依然可以找到該元素。**return S.data[S.top];**就是將該元素的值返回,以便下次能夠快速找到。
int PopStack(seqstack& S) { if (S.top == -1) { printf("棧為空,沒有元素輸出!"); } { printf("當(dāng)前棧頂元素為:"); return S.data[S.top]; S.top = S.top - 1; } }
關(guān)于順序棧的其他操作都是比較簡(jiǎn)單的,這里就不一一進(jìn)行講解了,需要注意的事項(xiàng)我會(huì)在下面的完整代碼中注釋出來!
順序棧的缺點(diǎn)
棧的大小不可發(fā)生變化。
出棧順序的計(jì)算方法
如上圖所示:
進(jìn)棧順序?yàn)閍->b->c->d->e,則對(duì)應(yīng)的出棧順序?yàn)閑->d->c->b->a
但有時(shí)候出棧和進(jìn)棧是穿插進(jìn)行的:
舉例:
這種進(jìn)棧出棧穿插的方式有很多種。
由此,我們可以得出一個(gè)結(jié)論:
鏈棧
既然上文都說到“棧”和“隊(duì)列”都是一種“特殊的”線性表”,那么鏈棧,顧名思義就是按照鏈?zhǔn)酱鎯?chǔ)的棧。
基本實(shí)現(xiàn)方法和單鏈表相同,這里就不一一進(jìn)行講解了,需要注意的事項(xiàng)我會(huì)在下面的完整代碼中注釋出來!
鏈棧完整代碼如下:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #define size 5 typedef struct LinkNode { int data; struct LinkNode* next; }Linkstack; //初始化 void Iniststack(Linkstack *L) { L= (LinkNode*)malloc(sizeof(LinkNode)); if (!L->data) { printf("申請(qǐng)失敗"); } else { L->data = 0; L->next = NULL; } } //入棧 void Pushstack(Linkstack *L) { int e,x; printf("請(qǐng)輸入你要?jiǎng)?chuàng)建的鏈棧長(zhǎng)度:"); scanf("%d", &x); printf("請(qǐng)輸入你要入棧的元素:\n"); for (int i = 0; i < x; i++) { LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode)); scanf("%d", &e); s->data = e; s->next = L->next; L->next = s; } } //出棧 int Popstack(Linkstack* L) { LinkNode* s= L->next; s->data = L->data; L->next = s->next; return s->data; } //讀取棧頂元素 int Getstack(Linkstack* L) { if (!L->data) { printf("棧為空!"); } else { int e = L->next->data; return e; } } //輸出棧中元素 void Printsatck(Linkstack* L) { if (!L->data) { printf("棧為空!"); } else { LinkNode* p; p = L; printf("棧中元素如下:"); while (p) { p = p->next; printf("%d", p->data); } } } int main() { Linkstack L; Iniststack(&L); Pushstack(&L); Popstack(&L); Getstack(&L); Printsatck(&L); }
輸出:
順序棧完整代碼如下:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #define size 5 typedef struct { int data[size]; int top; }seqstack; //初始化操作 void InistStack(seqstack &S) { S.top = -1; } //判空操作 void IsEmpty(seqstack& S) { if (S.top == -1) printf("目前棧為空!\n"); } //入棧操作 void Pushstack(seqstack& S) { if (S.top == size) printf("棧滿,拒絕元素繼續(xù)入棧!"); else { printf("請(qǐng)依次輸入你要入棧的元素:\n"); int x,i; for (i = 0; i < size; i++) { scanf("%d", &x); S.top = S.top + 1; S.data[S.top] = x; printf("入棧成功!\n"); } } } //讀取棧頂元素 void Getstack(seqstack& S) { if (S.top == -1) { printf("棧為空,沒有元素輸出!"); } { printf("當(dāng)前棧頂元素為:"); printf("%d\n", S.data[S.top]); } } //輸出棧中元素 void Printstack(seqstack& S) { if (S.top == -1) { printf("棧為空,沒有元素輸出!"); } else { printf("棧中元素如下:"); for (int i = 0; i < size; i++) { printf("%d", S.data[i]); } printf("\n"); } } //出棧 int PopStack(seqstack& S) { if (S.top == -1) { printf("棧為空,沒有元素輸出!"); } { printf("當(dāng)前棧頂元素為:"); return S.data[S.top]; S.top = S.top - 1; } } //刪除棧頂元素 int Deletestack(seqstack& S) { if (S.top == -1) { printf("棧為空!\n"); } else { int e; for (int i = 0; i < size; i++) { e = S.data[S.top]; S.top = S.top - 1; return e; } printf("所有元素已被刪除!\n"); } } //清棧 void Clearstack(seqstack& S) { S.top = -1; printf("棧已經(jīng)被清空!\n"); } int main() { seqstack S; int x; InistStack(S); IsEmpty(S); Pushstack(S); Getstack(S); Printstack(S); /*x=PopStack(S);*/ Deletestack(S); Clearstack(S); Printstack(S); }
輸出:
以上就是C語言中順序棧和鏈棧的定義和使用詳解的詳細(xì)內(nèi)容,更多關(guān)于C語言順序棧 鏈棧的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C語言實(shí)現(xiàn)通訊錄的八種功能(添加、刪除、查找、修改、顯示、排序、退出、清空)
本文主要介紹了C語言實(shí)現(xiàn)通訊錄的八種功能,主要包括添加、刪除、查找、修改、顯示、排序、退出、清空,感興趣的可以了解一下2023-09-09C++ Boost MetaStateMachine定義狀態(tài)機(jī)超詳細(xì)講解
Boost是為C++語言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱2022-12-12C語言數(shù)據(jù)結(jié)構(gòu)之棧和隊(duì)列的實(shí)現(xiàn)及應(yīng)用
棧和隊(duì)列是一種數(shù)據(jù)結(jié)構(gòu),只規(guī)定了性質(zhì),并沒有規(guī)定實(shí)現(xiàn)方式。本文將以順序結(jié)構(gòu)實(shí)現(xiàn)棧,鏈表方式實(shí)現(xiàn)隊(duì)列,感興趣的小伙伴快跟隨小編一起學(xué)習(xí)一下吧2022-08-08