數據結構——順序棧seq_stack

前言:大家好😍,本文主要介紹了數據結構——順序棧

目錄

一、概念

1.1 順序棧的基本概念

1.2 順序棧的存儲結構

二、基本操作

2.1 結構體定義

2.2 初始化?

2.3 判空

2.4 判滿

2.5 擴容

2.6 插入 入棧

2.7 刪除 出棧

2.8 獲取棧頂元素

2.9 獲取有效值長度

2.10 清空

2.11 銷毀

2.12 打印

2.13 測試


一、概念

順序棧是棧的一種實現方式,它是基于順序存儲結構(通常是數組或動態分配的內存空間)實現的棧。棧是一種**后進先出(LIFO,Last In First Out)**的數據結構,這意味著最后放入棧中的元素會最先被取出。

1.1 順序棧的基本概念

  1. 棧的定義

    • 棧是一種線性表,其操作主要在表的一端進行,這一端稱為棧頂(Top),另一端稱為棧底(Bottom)

    • 棧的操作遵循**后進先出(LIFO)**的原則,即最后放入棧中的元素最先被取出。

  2. 順序棧的特點

    • 順序棧使用連續的內存空間來存儲棧中的元素,通常通過數組或動態分配的內存來實現。

    • 棧底的位置是固定的,通常用一個指針(如base)來標記棧底。

    • 棧頂的位置是動態變化的,用一個指針(如top)來表示棧頂的位置。

1.2 順序棧的存儲結構

順序棧的存儲結構通常包括以下部分:

ps是一個指向Seq_Stack結構體的指針,所以? ? ps可以指向結構體的成員

  • base:指向棧底的指針,標記棧的起始位置。

  • top:棧頂指針,表示棧頂的位置。top的值通常等于棧中元素的數量。

  • stacksize:表示棧的總容量,即棧可以存儲的最大元素數量。

二、基本操作

2.1 結構體定義

typedef char ELEM_TYPE;
#define INITSIZE 10//*2struct Seq_Stack
{ELEM_TYPE* base;//指針,用來接收malloc的返回值int top;//棧頂指針int stacksize;//當前總的格子數
};
typedef struct Seq_Stack Seq_Stack;
typedef struct Seq_Stack* PSeq_Stack;

base是一個指針,它的作用是標記棧的底部位置,也就是這塊連續內存空間的起始地址。有了base,我們就能找到棧的“根基”,從而操作整個棧。無論棧頂指針top如何變化(入棧或出棧),base始終指向棧的底部,確保我們不會迷失方向。

2.2 初始化?

void Init_Seq_Stack(Seq_Stack* ps)
{assert(ps != NULL);ps->base = (ELEM_TYPE*)malloc(INITSIZE * sizeof(ELEM_TYPE));if (ps->base == NULL)//內存分配失敗{exit(1);//程序調用exit終止運行}ps->top = 0;ps->stacksize = INITSIZE;
}
  • 參數Seq_Stack* ps 是一個指向Seq_Stack結構體的指針。這個結構體定義了棧的基本屬性,比如棧底指針、棧頂指針和棧的容量等。

  • ps->base:這是棧底指針,用來存儲malloc分配的內存地址分配完內存后,ps->base就指向了這塊內存的起始位置,也就是棧的底部。malloc:這是一個動態內存分配函數,用來在堆上分配一塊內存空間

  • ps->top = 0:棧頂指針top初始化為0。在順序棧中,top的值通常表示棧中元素的數量。初始時棧為空,所以top為0。

  • ps->stacksize = INITSIZE:將棧的總容量stacksize設置為初始大小INITSIZE。這樣我們就知道棧一開始可以存儲多少個元素。

  • 通過ps,函數可以訪問和修改這個棧的內部數據(如basetopstacksize)。

2.3 判空

//2.判空(判斷順序表有沒有元素)
bool Is_Empty(Seq_Stack* ps)
{if (ps == NULL)exit(1);return ps->top ==0;
}
  • 這個指針ps就是用來告訴函數“我要檢查的是哪一個棧”。

  • if (ps == NULL)來檢查指針是否為空。如果是空的,說明傳入的棧是無效的,程序會調用exit(1)終止運行,避免后續操作出錯。

2.4 判滿

bool Is_Full(Seq_Stack* ps)
{if (ps == NULL)return false;return ps->top == ps->stacksize;
}

2.5 擴容

//4.擴容
static void Inc(Seq_Stack*ps)
{assert(ps != NULL);if (ps == NULL)return;ELEM_TYPE* tmp = (ELEM_TYPE*)realloc(ps->base, ps->stacksize * sizeof(ELEM_TYPE) * 2);if (tmp != NULL)ps->base = tmp;ps->stacksize *= 2;
}

Inc函數用于將順序棧的容量加倍。從而允許更多的元素入棧。

  • realloc:這是一個動態內存分配函數,用來重新分配一塊內存空間。它接受兩個參數:

    • 第一個參數是當前內存塊的指針(這里是ps->base)。

    • 第二個參數是新的內存大小(這里是ps->stacksize * sizeof(ELEM_TYPE) * 2)。ps->stacksize是當前棧的容量,sizeof(ELEM_TYPE)是每個元素的大小,* 2表示將容量加倍。

    • tmp:這是一個臨時指針,用來存儲realloc返回的新內存地址。如果realloc成功,它會返回新的內存塊的指針;如果失敗,它會返回NULL

    • 如果tmp不為NULL,說明realloc成功,新的內存已經分配好了。此時,ps所指向的結構體中的base成員更新為tmp的值。,即讓棧底指針指向新的內存地址。

    • 將棧的總容量stacksize加倍。

2.6 插入 入棧

//插入元素(入棧/壓棧)   Push
bool Push(Seq_Stack* ps, ELEM_TYPE val)
{assert(ps != NULL);if (ps == NULL)return false;if (Is_Full(ps)){Inc(ps);}ps->base[ps->top] = val;ps->top++;return true;
}
  • ps->base[ps->top] = val;:將新元素val插入到棧頂位置。ps->top表示棧頂指針,ps->base[ps->top]表示棧頂位置的內存地址。這里將新元素val存儲到棧頂位置。

  • ps->top++;:將棧頂指針ps->top加1,表示棧中元素的數量增加了一個。

2.7 刪除 出棧

bool Pop(Seq_Stack* ps)
{assert(ps != NULL);if (ps == NULL)return false;if (Is_Empty(ps))return false;ps->top--;return true;
}

2.8 獲取棧頂元素

ELEM_TYPE Top(Seq_Stack* ps)
{assert(ps != NULL);if (ps == NULL)exit(1);if (Is_Empty(ps))exit(1);return ps->base[ps->top - 1];return true;
}
  • ps->base[ps->top - 1]:棧頂元素的索引是ps->top - 1,因為ps->top表示棧中元素的數量,而數組索引是從0開始的。因此,ps->base[ps->top - 1]表示棧頂元素的值。

2.9 獲取有效值長度

//5.獲取有效值長度  Size
int Get_length(Seq_Stack* ps)
{assert(ps != NULL);if (ps == NULL)return -1;return ps->top;
}

2.10 清空

//6.清空  不需要free
void Clear(Seq_Stack* ps)
{assert(ps != NULL);if (ps == NULL)return;ps->top = 0;
}

2.11 銷毀

//7.銷毀 需要free
void Destroy(Seq_Stack* ps)
{assert(ps != NULL);if (ps == NULL)return;free(ps->base);ps->base = NULL;ps->top = ps->stacksize = 0;
}

Destroy函數的作用是銷毀一個順序棧,并釋放它所占用的動態內存。?

  • 調用free(ps->base)會釋放ps->base指向的內存空間。釋放內存后,這塊內存就不再屬于程序了,程序不能再使用它。

2.12 打印

//8.打印
void Show(Seq_Stack* ps)
{//assertfor (int i = 0; i < ps->top; i++){printf("%c ", ps->base[i]);}printf("\n");
}
  • ps->base:這是棧底指針,指向棧的起始內存地址。

  • ps->base[i]:表示棧中第i個元素的值。數組名本質上是一個指向數組首元素的指針。eg:arr&arr[0]是等價的,都表示數組的起始地址。

2.13 測試

//順序棧測試用例
int main()
{/*srand((unsigned int)time(NULL));int tmp = rand() % 29 + 1;printf("%d\n", tmp);*/Seq_Stack head;Init_Seq_Stack(&head);Push(&head, 'A');Push(&head, 'B');Push(&head, 'C');Show(&head);//A B Cprintf("%c\n", Top(&head));//CPop(&head);//A BShow(&head);//A B return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/75634.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/75634.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/75634.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++20 中的std::c8rtomb和 std::mbrtoc8

文章目錄 1. 引言2. std::c8rtomb 函數詳解3. std::mbrtoc8 函數詳解4. 使用示例5. 注意事項6. 總結 1. 引言 C20 標準引入了對 UTF-8 編碼的更好支持&#xff0c;其中包括兩個重要的函數&#xff1a;std::c8rtomb 和 std::mbrtoc8。這兩個函數分別用于將 UTF-8 編碼的字符轉換…

AI音樂生成革命:解讀昆侖萬維Mureka O1的技術突破與應用實踐

AI音樂生成革命&#xff1a;解讀昆侖萬維Mureka O1的技術突破與應用實踐 全球音樂產業正經歷AI技術重塑&#xff0c;昆侖萬維最新發布的音樂推理大模型Mureka O1引發行業震動。本文深度解析其技術原理與實測表現&#xff0c;揭開AI音樂創作新紀元的技術密碼 一、技術演進&…

《Operating System Concepts》閱讀筆記:p483-p488

《Operating System Concepts》學習第 40 天&#xff0c;p483-p488 總結&#xff0c;總計 6 頁。 一、技術總結 1.object storage (1)object storage 管理軟件 Hadoop file system(HDFS)、Ceph。 二、英語總結(生詞&#xff1a;1) 1.commodity (1)commodity: com-(“tog…

強化學習與神經網絡結合(以 DQN 展開)

目錄 基于 PyTorch 實現簡單 DQN double DQN dueling DQN Noisy DQN&#xff1a;通過噪聲層實現探索&#xff0c;替代 ε- 貪心策略 Rainbow_DQN如何計算連續型的Actions 強化學習中&#xff0c;智能體&#xff08;Agent&#xff09;通過與環境交互學習最優策略。當狀態空間或動…

“11.9元“引發的系統雪崩:Spring Boot中BigDecimal反序列化異常全鏈路狙擊戰 ?

&#x1f4a5; "11.9元"引發的系統雪崩&#xff1a;Spring Boot中BigDecimal反序列化異常全鏈路狙擊戰 &#x1f3af; &#x1f50d; 用 Mermaid原生防御體系圖 #mermaid-svg-XZtcYBnmHrF9bFjc {font-family:"trebuchet ms",verdana,arial,sans-serif;fon…

Cortex-M7進入異常中斷分析

使用cmbacktrace庫&#xff0c;其支持M3,4,7。 1、串口輸出異常信息 #define cmb_println(...) Debug_Printf(__VA_ARGS__)//cmb_println處理可變參數和格式化字符串 int Debug_Printf(const char *fmt, ...) {char buffer[DEBUG_TxBUFLEN];INT16U n;va_list args;va_star…

如何管理間接需求?團隊實踐分享

管理間接需求的核心方法包括明確需求識別流程、建立規范的需求管理體系、實施有效的需求溝通機制。 其中&#xff0c;明確需求識別流程最為關鍵。企業在實際業務中&#xff0c;往往會遇到大量的間接需求&#xff0c;如非直接生產性的采購需求、服務類需求等。這些需求往往隱蔽性…

與Aspose.pdf類似的jar庫分享

如果你在尋找類似于 Aspose.PDF 的 JAR 庫&#xff0c;這些庫通常用于處理 PDF 文檔的創建、編輯、轉換、合并等功能。以下是一些類似的 Java 庫&#xff0c;它們提供 PDF 處理的功能&#xff0c;其中一些是收費的&#xff0c;但也有開源選項&#xff1a; 1. iText (iText PDF…

2-2 MATLAB鮣魚優化算法ROA優化CNN超參數回歸預測

本博客來源于CSDN機器魚&#xff0c;未同意任何人轉載。 更多內容&#xff0c;歡迎點擊本專欄目錄&#xff0c;查看更多內容。 目錄 0.引言 1.ROA優化CNN 2.主程序調用 3.結語 0.引言 在博客【ROA優化LSTM超參數回歸】中&#xff0c;我們采用ROA對LSTM的學習率、迭代次數…

企業入駐成都國際數字影像產業園,可享150多項專業服務

企業入駐成都國際數字影像產業園&#xff0c;可享150多項專業服務 全方位賦能&#xff0c;助力影像企業騰飛 入駐成都國際數字影像產業園&#xff0c;企業將獲得一個涵蓋超過150項專業服務的全周期、一站式支持體系&#xff0c;旨在精準解決企業發展各階段的核心需求&#xf…

線路板元器件介紹及選型指南:提高電路設計效率

電路板&#xff08;PCB&#xff09;是現代電子設備的核心&#xff0c;其上安裝了各類電子元器件&#xff0c;這些元器件通過PCB的導電線路彼此連接&#xff0c;實現信號傳輸與功能執行。 元器件的選擇與安裝直接決定了電子產品的性能與穩定性。本文將為大家詳細介紹電路板上的…

探究 Arm Compiler for Embedded 6 的 Clang 版本

原創標題&#xff1a;Arm Compiler for Embedded 6 的 Clang 版本 原創作者&#xff1a;莊曉立&#xff08;LIIGO&#xff09; 原創日期&#xff1a;20250218&#xff08;首發日期20250326&#xff09; 原創連接&#xff1a;https://blog.csdn.net/liigo/article/details/14653…

RedHat7.6_x86_x64服務器(最小化安裝)搭建使用記錄(二)

PostgreSQL數據庫部署管理 1.rpm方式安裝 掛載系統安裝鏡像&#xff1a; [rootlocalhost ~]# mount /dev/cdrom /mnt 進入安裝包路徑&#xff1a; [rootlocalhost ~]# cd /mnt/Packages 依次安裝如下程序包&#xff1a; [rootlocalhost Packages]# rpm -ihv postgresql-libs-9…

瀏覽器存儲 IndexedDB

IndexedDB 1. 什么是 IndexedDB&#xff1f; IndexedDB 是一種 基于瀏覽器的 NoSQL 數據庫&#xff0c;用于存儲大量的結構化數據&#xff0c;包括文件和二進制數據。它比 localStorage 和 sessionStorage 更強大&#xff0c;支持索引查詢、事務等特性。 IndexedDB 主要特點…

panda3d 渲染

目錄 安裝 設置渲染寬高&#xff1a; 渲染3d 安裝 pip install Panda3D 設置渲染寬高&#xff1a; import panda3d.core as pdmargin 100 screen Tk().winfo_screenwidth() - margin, Tk().winfo_screenheight() - margin width, height (screen[0], int(screen[0] / 1…

Node.js 包管理工具 - NPM 與 PNPM 清理緩存

NPM 清理緩存 1、基本介紹 npm 緩存是 npm 用來存儲已下載包的地方&#xff0c;以加快后續安裝速度 但是&#xff0c;有時緩存可能會損壞或占用過多磁盤空間&#xff0c;這時可以清理 npm 緩存 2、清理操作 執行如下指令&#xff0c;清理 npm 緩存 npm cache clean --for…

STM32F103_LL庫+寄存器學習筆記05 - GPIO輸入模式,捕獲上升沿進入中斷回調

導言 GPIO設置輸入模式后&#xff0c;一般會用輪詢的方式去查看GPIO的電平狀態。比如&#xff0c;最常用的案例是用于檢測按鈕的當前狀態&#xff08;是按下還是沒按下&#xff09;。中斷的使用一般用于計算脈沖的頻率與計算脈沖的數量。 項目地址&#xff1a;https://github.…

【C++進階二】string的模擬實現

【C進階二】string的模擬實現 1.構造函數和C_strC_str: 2.operator[]3.拷貝構造3.1淺拷貝3.2深拷貝 4.賦值5.迭代器6.比較ascll碼值的大小7.reverse擴容8.push_back尾插和append尾插9.10.insert10.1在pos位置前插入字符ch10.2在pos位置前插入字符串str 11.resize12.erase12.1從…

wokwi arduino mega 2560 - 點亮LED案例

截圖&#xff1a; 點亮LED案例仿真截圖 代碼&#xff1a; unsigned long t[20]; // 定義一個數組t&#xff0c;用于存儲20個LED的上次狀態切換時間&#xff08;單位&#xff1a;毫秒&#xff09;void setup() {pinMode(13, OUTPUT); // 將引腳13設置為輸出模式&#xff08;此…

vue3項目使用 python +flask 打包成桌面應用

server.py import os import sys from flask import Flask, send_from_directory# 獲取靜態文件路徑 if getattr(sys, "frozen", False):# 如果是打包后的可執行文件base_dir sys._MEIPASS else:# 如果是開發環境base_dir os.path.dirname(os.path.abspath(__file…