【數據結構】實現棧

大家好,我是蘇貝,本篇博客帶大家了解棧,如果你覺得我寫的還不錯的話,可以給我一個贊👍嗎,感謝??
在這里插入圖片描述


目錄

  • 一 .棧的概念及結構
  • 二 .棧的實現
    • 棧的結構體
    • 初始化
    • 銷毀
    • 棧頂插入
    • 棧頂刪除
    • 顯示棧頂元素
    • 是否為空
    • 棧的大小
  • 三. 模塊化代碼實現
    • Stack.h
    • Stack.c
    • Test.c
    • 結果演示

一 .棧的概念及結構

:一種特殊的線性表,其只允許在固定的一端進行插入和刪除元素操作。進行數據插入和刪除操作的一端稱為棧頂,另一端稱為棧底。棧中的數據元素遵守后進先出LIFO(Last In First Out)的原則。
壓棧:棧的插入操作叫做進棧/壓棧/入棧,入數據在棧頂
出棧:棧的刪除操作叫做出棧,出數據也在棧頂

在這里插入圖片描述


二 .棧的實現

棧的實現一般可以使用數組或者鏈表實現,相對而言數組的結構實現更優一些,因為數組在尾上插入數據的代價比較小(數組的尾插、尾刪很方便)。所以下面我們用數組來實現
在這里插入圖片描述

1

棧的結構體

typedef int STDataType;
#define N 10
typedef struct Stack
{STDataType _a[N];int top; // 棧頂
}ST;

上面是定長的靜態棧的結構,實際中一般不實用,所以我們主要實現下面的支持動態增長的棧

typedef int STDataType;typedef struct Stack
{STDataType* a;int top;//棧頂int capacity;//容量
}ST;

2

初始化

因為我們要對ST類型的變量進行初始化,所以實參要傳ST類型變量的地址,用一級指針來接收。因為實參(ST類型變量的地址)不可能為NULL,所以對它斷言(下面的接口同理)。
注意:我們這里的top指的是棧頂元素的下一個,而非棧頂元素,所以將它初始化為0

void STInit(ST* pst)
{assert(pst);pst->a = NULL;pst->capacity = 0;pst->top = 0;//指向棧頂元素的下一個
}

3

銷毀

注意:在這里我們使用的是動態開辟內存,所以要在銷毀時釋放掉動態開辟的內存,也就是pst->a指向的那個數組

void STDestroy(ST* pst)
{assert(pst);if (pst->a != NULL){free(pst->a);pst->a = NULL;pst->capacity = 0;pst->top = 0;}
}

4

棧頂插入

再插入元素之前我們要先判斷是否要增容,因為在初始化時我們將pst->capacity初始化為0,所以在增容時要特別注意將pst->capacity==0的情況。還要注意對realloc的結果進行判斷,防止realloc失敗返回NULL,又直接將NULL賦值給pst->a,這樣就再找不到開辟的數組了。
最后不要忘記pst->top++

void STPush(ST* pst, STDataType x)
{assert(pst);//判斷是否需要增容if (pst->top == pst->capacity){int newcapacity = (pst->capacity == 0) ? 4 : 2 * pst->capacity;ST* tmp = (ST*)realloc(pst->a, newcapacity * sizeof(ST));if (tmp == NULL){perror("realloc fail");return;}pst->a = tmp;pst->capacity = newcapacity;}//插入數據pst->a[pst->top] = x;pst->top++;
}

5

棧頂刪除

刪除時我們必須保證棧內有元素,所以要對pst->top>0斷言,如果top==0,表示棧內已無元素,返回錯誤信息,下面的顯示棧頂元素同理

void STPop(ST* pst)
{assert(pst);assert(pst->top > 0);pst->top--;
}

6

顯示棧頂元素

STDataType STTop(ST* pst)
{assert(pst);assert(pst->top > 0);return pst->a[pst->top - 1];
}

7

是否為空

bool STEmpty(ST* pst)
{assert(pst);return pst->top == 0;
}

8

棧的大小

int STSize(ST* pst)
{assert(pst);return pst->top;
}

三. 模塊化代碼實現

Stack.h

#include<stdio.h>
#include<assert.h>
#include<stdbool.h>typedef int STDataType;typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;//初始化
void STInit(ST* pst);
//銷毀
void STDestroy(ST* pst);
//棧頂插入
void STPush(ST* pst, STDataType x);
//棧頂刪除
void STPop(ST* pst);
//顯示棧頂元素
STDataType STTop(ST* pst);
//是否為空
bool STEmpty(ST* pst);
//大小
int STSize(ST* pst);

Stack.c

#include"Stack.h"//初始化
void STInit(ST* pst)
{assert(pst);pst->a = NULL;pst->capacity = 0;pst->top = 0;//指向棧頂元素的下一個
}//銷毀
void STDestroy(ST* pst)
{assert(pst);if (pst->a != NULL){free(pst->a);pst->a = NULL;pst->capacity = 0;pst->top = 0;}
}//棧頂插入
void STPush(ST* pst, STDataType x)
{assert(pst);//判斷是否需要增容if (pst->top == pst->capacity){int newcapacity = (pst->capacity == 0) ? 4 : 2 * pst->capacity;ST* tmp = (ST*)realloc(pst->a, newcapacity * sizeof(ST));if (tmp == NULL){perror("realloc fail");return;}pst->a = tmp;pst->capacity = newcapacity;}//插入數據pst->a[pst->top] = x;pst->top++;
}//棧頂刪除
void STPop(ST* pst)
{assert(pst);assert(pst->top > 0);pst->top--;
}//顯示棧頂元素
STDataType STTop(ST* pst)
{assert(pst);assert(pst->top > 0);return pst->a[pst->top - 1];
}//是否為空
bool STEmpty(ST* pst)
{assert(pst);return pst->top == 0;
}//大小
int STSize(ST* pst)
{assert(pst);return pst->top;
}

Test.c

#include"Stack.h"int main()
{ST s;STInit(&s);STPush(&s, 1);STPush(&s, 2);STPush(&s, 3);STPush(&s, 4);STPush(&s, 5);while (!STEmpty(&s)){printf("%d  ", STTop(&s));STPop(&s);}printf("\n");return 0;
}

結果演示

在這里插入圖片描述


好了,那么本篇博客就到此結束了,如果你覺得本篇博客對你有些幫助,可以給個大大的贊👍嗎,感謝看到這里,我們下篇博客見??

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

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

相關文章

USB - Linux Kernel Menuconfig

Linux kernel&#xff0c;make menuconfig&#xff0c;和USB相關的&#xff0c;在主菜單選擇Device Drivers。 Device Drivers下面&#xff0c;找到USB support。 在USB support下面&#xff0c;就可以對USB相關的item進行設置。 按照從上到下的順序&#xff0c;打開的設置依次…

【大數據】-- dataworks 創建odps 的 hudi 外表

文檔:創建OSS外部表_云原生大數據計算服務 MaxCompute(MaxCompute)-阿里云幫助中心 舉例:創建 odps 的 hudi 外表 CREATE EXTERNAL TABLE IF NOT EXISTS my_project.ods_hudi_mysql_words_h_all (id BIGINT COMMENT 主鍵id,`words` STRING COMMENT 詞…

【C++入門】缺省參數 | 函數重載

目錄 4.缺省參數 4.1缺省參數的概念 4.2缺省參數分類 4.3聲明和定義分離&#xff08;聲明使用缺省參數&#xff09; 4.&#x1f40d;聲明和定義分離到鏈接 5.函數重載 5.1函數重載的概念 5.2可執行程序的形成步驟 5.3C支持函數重載的原理—名字修飾(name Mangling) 4.…

Linux學習之信號

目錄 1.信號的概念 2.信號的產生 3.信號的保存 4.信號的捕捉 信號的其它內容&#xff1a; SIGCHLD信號 1.信號的概念 在Linux中&#xff0c;信號是一種用于進程之間通信的基本機制。它是一種異步事件通知&#xff0c;用于通知進程發生了某些事件。如下是一些常見的Linux信…

[計算機網絡]--五種IO模型和select

前言 作者&#xff1a;小蝸牛向前沖 名言&#xff1a;我可以接受失敗&#xff0c;但我不能接受放棄 如果覺的博主的文章還不錯的話&#xff0c;還請點贊&#xff0c;收藏&#xff0c;關注&#x1f440;支持博主。如果發現有問題的地方歡迎?大家在評論區指正 目錄 一、五種IO…

線性規劃問題的高斯消元法

線性規劃的算法和解方程組的方法很像,常用的方程組的解法叫做高斯消元法,對于高斯消元法的基本流程,現給定一組線性方程: 添加圖片注釋,不超過 140 字(可選) 對于給定的線性方程組,目的是將方程組中同時能夠滿足三個等式的變量x,y,z求解出來,對于高斯消元法的基本過程…

【精通Spring】基于注解管理Bean

個人名片&#xff1a; &#x1f43c;作者簡介&#xff1a;一名大三在校生&#xff0c;喜歡AI編程&#x1f38b; &#x1f43b;???個人主頁&#x1f947;&#xff1a;落798. &#x1f43c;個人WeChat&#xff1a;hmmwx53 &#x1f54a;?系列專欄&#xff1a;&#x1f5bc;?…

集智書童 | YOLO+混合注意力機制 | YOLOv5再加4.3%才可以做對手,Transformer混合設計依舊可以卷

本文來源公眾號“集智書童”&#xff0c;侵權刪&#xff0c;干貨滿滿。YOLOv5重出江湖&#xff01; 原文鏈接&#xff1a;https://mp.weixin.qq.com/s/vb7HsA0fKDgRc3uC8Z-2yw 在工業生產過程中&#xff0c;由于低效率、不統一的評估、高成本以及缺乏實時數據&#xff0c;傳統…

LeetCode //C - 32. Longest Valid Parentheses

32. Longest Valid Parentheses Given a string containing just the characters ‘(’ and ‘)’, return the length of the longest valid (well-formed) parentheses substring. Example 1: Input: s “(()” Output: 2 Explanation: The longest valid parentheses s…

【刷題1】LeetCode 994. 腐爛的橘子 java題解

tag:圖論 廣度優先搜索 https://leetcode.cn/problems/rotting-oranges/description/?envTypestudy-plan-v2&envIdtop-100-liked 使用廣度優先搜索&#xff0c;搜索步數就是分鐘數&#xff0c;等到所有橘子都腐爛后&#xff0c;各個橘子腐爛的最長分鐘數就是全部都爛的最小…

C語言-指針(上)

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、pandas是什么&#xff1f;二、使用步驟 1.引入庫2.讀入數據總結 前言 本篇文章將為大家介紹C語言中的核心內容-指針&#xff0c;指針在C語言的中知識內容比…

【文件管理】關于上傳下載文件的設計

這里主要談論的是產品設計里面的文件管理&#xff0c;比如文件的上傳交互及背后影響到的前后端設計。 上傳文件 場景&#xff1a;一條記錄&#xff0c;比如個人信息&#xff0c;有姓名&#xff0c;出生年月&#xff0c;性別等一般的字段&#xff0c;還可以允許用戶上傳附件作為…

Java 小項目開發日記 04(文章接口的開發、oss圖片上傳)

Java 小項目開發日記 04&#xff08;文章接口的開發、oss圖片上傳&#xff09; 項目目錄 配置文件&#xff08;pom.xml&#xff09; <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sc…

機器學習:集成學習(Python)

一、Adaboost算法 1.1 Adaboost分類算法 adaboost_discrete_c.py import numpy as np import copy from ch4.decision_tree_C import DecisionTreeClassifierclass AdaBoostClassifier:"""adaboost分類算法&#xff1a;既可以做二分類、也可以做多分類&#…

python常用pandas函數nlargest 和 nsmallest及其手動實現

pandas是Python數據分析的重要工具之一&#xff0c;提供了大量便捷的數據操作方法。nlargest和nsmallest是pandas中兩個非常實用的函數&#xff0c;它們可以幫助我們快速找出Series或DataFrame中最大或最小的n個值。 ### pandas中的nlargest和nsmallest函數 - nlargest(n, colu…

掌握Go語言:深入探究Go語言中的命令源碼文件與參數處理技巧(3)

在Go語言學習的路上&#xff0c;掌握命令源碼文件與參數處理技巧是至關重要的。本文將深入探討命令源碼文件的概念、作用以及參數處理的方法&#xff0c;同時結合進銷存項目&#xff0c;展示實際應用與代碼示例。 命令源碼文件的概述 命令源碼文件是Go語言程序的運行入口&…

uniapp的h5端在線預覽文件

步驟如下&#xff1a; 1、下載需要準備的工具文件包 2、將其解壓到/static/pdf文件夾下,如圖&#xff1a; 3、創建在線查看文件的頁面&#xff1a; <template><view><web-view :src"path"></web-view></view> </template>&l…

linux檢測和重啟python腳本

#!/bin/bash# 檢測Flask應用是否掛了 if ! pgrep -f "flask_app.py" >/dev/null; then# 重啟Flask應用cd /path/to/your/flask/appnohup python3 flask_app.py >/dev/null 2>&1 & fi這是一個簡單的bash腳本&#xff0c;用于檢測Flask應用是否掛掉&a…

JavaScript練手小技巧:一文看懂<script>標簽的 ansyc 和 defer

<script>標簽的 ansyc 和 defer 屬性。只對外部加載 JS 文件有效。 <script src"js/app.js" async></script> <script src"js/app.js" defer></script> 普通加載 js&#xff08;同步加載&#xff09;&#xff1a;會打斷 …

ES7、ES8、ES9、ES10、ES11、ES12 新特性匯總合集

在過去幾年里&#xff0c;ECMAScript 標準不斷更新&#xff0c;引入了許多令人激動的功能和改進。讓我們來看看從 ES7 到 ES12 各個版本帶來的重要變化&#xff1a; 1. ES7&#xff08;ECMAScript 2016&#xff09; 1. Array.prototype.includes 方法 Array.prototype.includ…