日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构-栈详解(类C语言版)

發布時間:2025/3/19 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构-栈详解(类C语言版) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

棧的定義

概念

棧的抽象數據類型定義

順序棧的基本操作

?存儲方式

順序棧的表示

順序棧的初始化

順序棧判斷是否為空

清空順序棧

?銷毀順序棧

順序棧的入棧

順序棧的出棧

?取順序棧的棧頂元素

鏈棧的基本操作

鏈棧的表示

鏈棧的初始化

判斷鏈棧是否為空

鏈棧的入棧

鏈棧的出棧

取棧頂元素

棧與遞歸

分治法求解遞歸問題算法的一般形式

尾遞歸轉變為循環結構

單向遞歸轉變為循環結構


棧的定義

概念

棧 (stack) 是限定僅在表尾進行插入或刪除操作的線性表。 因此, 對棧來說, 表尾端有其特殊含義, 稱為棧頂 (top), 相應地, 表頭端稱為棧底 (bottom)。 不含元素的空表稱為空棧。

棧又稱為后進先出 (Last In First Out, LIFO) 的線性表。

棧的抽象數據類型定義

ADT Stack {

數據對象:

? ? ? ? D = {ai | ai?∈ElemSet , i = 1,2,...,n,n≥0 }

數據關系:

? ? ? ? R1 = { <ai-1, ai > | ai-1, ai ∈ D, i=2,...,n }

? ? ? ? 約定an端為棧頂,a1端為棧底。

基本操作:初始化、進棧、出棧、取棧頂元素等

}ADT Stack

順序棧的基本操作

?存儲方式

同一般線性表的順序存儲結構完全相同。

利用一組地址連續的存儲單元依次存放自棧底到棧頂的數據元素。棧底一般在低地址端。

·?附設top指針,指示棧頂元素在順序棧中的位置。

·?另設base指針,指示棧底元素在順序棧中的位置。

(但是,為了方便操作,通常top指示真正棧頂元素之上的下標地址。)

·?另外,用stacksize表示??墒褂玫淖畲笕萘?。

?空棧:base==top是??諛酥?。

棧滿:top-base==stacksize

?下圖所示棧中元素和棧指針之間的關系

順序棧的表示

#define MAXSIZE 100 typedef struct {SElemType *base; // 棧底指針SElemType *top; // 棧頂指針int stacksize; // ??捎米畲笕萘?} SqStack;

順序棧的初始化

Status InitStack(SqStack &S) { // 構造一個空棧S.base = new SElemType[MAXSIZE]; // 或S.base = (SElemType*)malloc(MAXSIZE*sizeof(SelemType));if (!S.base) exit(OVERFLOW); // 存儲分配失敗S.top = S.base; // 棧頂指針等于棧底指針S.stacksize = MAXSIZE;return OK; }

順序棧判斷是否為空

棧頂指針等于棧底指針,就認為順序棧為空

Status StackEmpty(SqStack S) {// 若棧為空,返回TRUE;否則返回FALSE if (S.top == S.base)return TRUE;elsereturn FALSE; }

?

清空順序棧

清空順序棧就是將棧頂指針移到棧底指針。

Status ClearStack(SqStack S) {if(S.base) S.top = S.base;return OK; }

?銷毀順序棧

Status DestroyStack(SqStack &S) {if(S.base) {delete S.base;S.stacksize = 0;S.base = S.top = NULL;}return OK; }

順序棧的入棧

①?判斷是否棧滿,若滿則出錯(上溢)。

②?元素e壓入棧頂。

③?棧頂指針加1。

Status Push(SqStack &S, SElemType e) {if(S.top - S.base == S.stacksize) // 棧滿return ERROR;*S.top++=e; // 可以分開寫,*S.top=e;S.top++;return OK; }

順序棧的出棧

①?判斷是否棧空,若空則出錯(下溢)。

②?獲取棧頂元素e。

③?棧頂指針減1。

Status Pop(SqStack &S, SElemType &e) {// 若棧不空,則刪除S的棧頂元素,用e返回其值,并返回OK;否則返回ERRORif(S.top == S.base) // 等價于if(StackEmpty(S))return ERROR;e = *--S.top; // 可分解為兩步--S.top; e = *S.top;return OK; }

?取順序棧的棧頂元素

SElemType GetTop(SqStack S) {// 返回S的棧頂元素,不修改棧頂指針if(S.top != S.base) // 棧非空return *(S.top-1) // 返回棧頂元素的值,棧頂指針不變 }

鏈棧的基本操作

鏈棧的表示

鏈棧是運算受限的單鏈表,只能在鏈表頭部進行操作。

·?鏈表的頭指針就是棧頂。

·?不需要頭結點。

·?基本不存在棧滿的情況。

·?空棧相當于頭指針指向空。

·?插入和刪除僅在棧頂處執行。

注意:鏈棧中的指針方向。

typedef struct StackNode {SElemType data;struct StackNode *next; } StackNode, *LinkStack; LinkStack S;

鏈棧的初始化

void InitStack(LinkStack &S) {// 構造一個空棧,棧頂指針置為空S=NULL;return OK; }

判斷鏈棧是否為空

Status StackEmpty(LinkStack S) {if(S==NULL) return TRUE;else return FALSE; }

鏈棧的入棧

Status Push(LinkStack &S, SElemType e) {p = new StackNode; // 生成新結點pp -> data = e; // 將新結點數據域置為ep -> next = S; // 將新結點插入棧頂S = p; // 修改棧頂指針return OK; }

鏈棧的出棧

Status Pop(LinkStack &S, SElemType &e) {if (S == NULL) return ERROR;e = S -> data;p = S;S = S -> next;delete p;return OK; }

取棧頂元素

SElemType GetTop(LinkStack S) {if (S != NULL)return S -> data; }

棧與遞歸

分治法求解遞歸問題算法的一般形式

void p (參數表) {if(遞歸結束條件) 可直接求解步驟; ----- 基本項else p(較小的參數); -----歸納項 }

例如

long Fact(long n) {if(n == 0) return 1; // 基本項else return n * Fact(n-1); // 歸納項 }

尾遞歸轉變為循環結構

long Fact(long n) {if(n == 0) return 1;else return n * Fact(n-1); }

以上遞歸可以寫成循環結構

long Fact(long n) {t = 1;for(i = 1; i <= n; i++) t = t*i;return t; }

單向遞歸轉變為循環結構

雖然有一處以上的遞歸調用語句,但各次遞歸調用語句的參數只和主調函數有關,相互之間參數無關,并且這些遞歸調用語句處于算法的最后。

long Fib(long n) { // Fibonacci數列if(n==1||n==2) return 1;else return Fib(n-1) + Fib(n-2); }

?轉換為循環結構

long Fib(long n) {if(n==1||n==2) return 1;else {t1 = 1; t2 = 1;for(i=3;i<=n;i++){t3=t1+t2;t1=t2;t2=t3;}return t3;} }

總結

以上是生活随笔為你收集整理的数据结构-栈详解(类C语言版)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。