c語言數據結構(5)——棧

歡迎來到博主的專欄——C語言數據結構
博主id:代碼小豪

文章目錄

    • 棧的順序存儲結構
      • 棧的插入
      • 空棧的初始化
      • 棧的刪除
      • 判斷空棧
      • 讀取棧頂元素數據
    • 實現順序棧的所有代碼
    • 棧的鏈式存儲結構
      • 鏈式棧的初始化
      • 鏈式棧的入棧操作
      • 鏈式棧的出棧操作
    • 實現鏈式棧的所有代碼

棧是一個特殊線性表,其只能在表尾進行數據的插入與刪除,進行數據的插入與刪除的一端稱為棧頂 (TOP)。

我們可以將棧想象成一個酸菜壇子,往壇子中開始放菜的時候,壇中的酸菜是從底部開始增加的。

當壇子放滿酸菜后,我們開壇取出酸菜,酸菜會從頂部開始減少。

棧的順序存儲結構

前面提到了,棧是一個特殊的線性表,所以棧的儲存形式也可以像線性表一樣分為兩種,一種為順序存儲結構的棧(順序棧)。

既然順序棧是用順序結構實現的,那么就可以用數組來實現順序棧。

順序棧的結構聲明如下:

typedef int SDataType;
typedef struct SeqStack
{SDataType val[MAXSIZE];int TOP;
}SeqStack;

棧的插入

從棧頂插入數據的操作被稱為入棧(PUSH)
在這里插入圖片描述

將數據插入棧頂的位置,然后棧頂的位置往上挪動一位,用于下一次入棧操作。

為空時,棧頂的位置為0.
在這里插入圖片描述

還有一種空棧的表示方法,由于數組中第一個元素的下標是0,但是空棧就代表著0下標處沒有元素,所以空棧時,棧頂的位置為-1.
在這里插入圖片描述
如果用這個方法表示的空棧,在插入數據時應該先讓棧頂往上一步,再插入數據。
在這里插入圖片描述

void StackPush(SeqStack* stack, SDataType e)
{if (stack->TOP == MAXSIZE){perror("stack overflow\n");return;}stack->val[stack->TOP] = e;stack->TOP++;
}

空棧的初始化

將一個新生成的棧傳入函數進行初始化,初始化的方法根據入棧的形式而定(TOP為0或TOP為-1)

以前者為例,空棧的初始化的函數為

void StackInit(SeqStack* stack)
{stack->TOP = 0;
}

棧的刪除

從棧頂刪除數據的操作稱為出棧(POP)
在這里插入圖片描述

出棧的方式很簡單,我們不用將當前棧頂的數據進行處理,只需要將TOP的位置往下移動一格就行。

要注意當棧為空棧時的特殊情況,當棧為空棧時,出棧的操作會導致TOP位于非法的位置,當下次進行入棧操作時,就會發生數組越位的錯誤發生。

判斷空棧

判斷空棧的條件需要按照初始化時,棧頂的位置為準,以前者為例

bool StackEmpty(SeqStack* stack)
{return stack->TOP == 0;
}

如果TOP為0,那么該函數返回值為true。反之為false。

出棧的函數需要調用判斷空棧的函數,如下:

void StackPop(SeqStack* stack)
{if (StackEmpty(stack)){perror("stack is empty\n");return;}stack->top--;
}

讀取棧頂元素數據

SDataType StackTop(SeqStack* stack)
{return stack->val[stack->top - 1];
}

實現順序棧的所有代碼

typedef int SDataType;
typedef struct SeqStack
{SDataType val[MAXSIZE];int top;
}SeqStack;void ListStackInit(ListStack* stack)
{assert(stack);stack->top = NULL;stack->lenth = 0;
}void ListStackPush(ListStack* stack, LDataType e)
{StackNode* newnode = malloc(sizeof(StackNode));assert(newnode);newnode->val = e;newnode->next = stack->top;stack->top = newnode;stack->lenth++;
}bool ListStackEmpty(ListStack* stack)
{return stack->top == NULL;
}void ListStackPop(ListStack* stack)
{if (!ListStackEmpty(stack)){perror("stack is empty\n");return;}StackNode* del = stack->top;stack->top = stack->top->next;free(del);
}LDataType ListStackTop(ListStack* stack)
{assert(stack);return stack->top->val;
}

棧的鏈式存儲結構

棧既然是線性表,就可以用鏈表的形式來實現。

棧是從表尾進行插入和刪除,鏈表可以用尾插\尾刪的方法實現出棧和入棧(?)。

在這里插入圖片描述

在這里插入圖片描述
可以發現,使用尾刪法是不能實現出棧操作的,因為單鏈表不能將TOP回到上一個數據的位置。

為了解決這個問題,我們將TOP的位置變為鏈表頭,將入棧和出棧的操作用頭插\頭刪法來實現。

在這里插入圖片描述
在這里插入圖片描述
鏈式棧的結構類型如下:

typedef int LDataType;
typedef struct StackNode
{LDataType val;struct StackNode* next;
}StackNode;typedef struct ListStack
{StackNode* top;int lenth;
};

鏈式棧的初始化

鏈式棧的初始化如下

void ListStackInit(ListStack* stack)
{assert(stack);stack->top = NULL;stack->lenth = 0;
}

鏈式棧的入棧操作

鏈式棧入棧使用頭插法。代碼如下:

void ListStackPush(ListStack* stack, LDataType e)
{StackNode* newnode = malloc(sizeof(StackNode));assert(newnode);newnode->val = e;newnode->next = stack->top;stack->top = newnode;stack->lenth++;
}

鏈式棧的出棧操作

考慮到鏈表空棧無法出棧,所以先定義一個判斷空棧的函數

bool ListStackEmpty(ListStack* stack)
{return stack->top == NULL;
}

鏈式棧出棧使用頭刪法。代碼如下:

void ListStackPop(ListStack* stack)
{if (ListStackEmpty(stack)){perror("stack is empty\n");return;}StackNode* del = stack->top;stack->top = stack->top->next;free(del);
}

實現鏈式棧的所有代碼

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int LDataType;
typedef struct StackNode
{LDataType val;struct StackNode* next;
}StackNode;typedef struct ListStack
{StackNode* top;int lenth;
}ListStack;void ListStackInit(ListStack* stack);
void ListStackPush(ListStack* stack,LDataType e);
void ListStackPop(ListStack* stack);
bool ListStackEmpty(ListStack* stack);
LDataType ListStackTop(ListStack* stack);void ListStackInit(ListStack* stack)
{assert(stack);stack->top = NULL;stack->lenth = 0;
}void ListStackPush(ListStack* stack, LDataType e)
{StackNode* newnode = malloc(sizeof(StackNode));assert(newnode);newnode->val = e;newnode->next = stack->top;stack->top = newnode;stack->lenth++;
}bool ListStackEmpty(ListStack* stack)
{return stack->top == NULL;
}void ListStackPop(ListStack* stack)
{if (ListStackEmpty(stack)){perror("stack is empty\n");return;}StackNode* del = stack->top;stack->top = stack->top->next;free(del);
}LDataType ListStackTop(ListStack* stack)
{assert(stack);return stack->top->val;
}

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

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

相關文章

學習網絡編程No.11【傳輸層協議之UDP】

引言&#xff1a; 北京時間&#xff1a;2023/11/20/9:17&#xff0c;昨天成功更文&#xff0c;上周實現了更文兩篇&#xff0c;所以這周再接再厲。當然做題任在繼續&#xff0c;而目前做題給我的感覺以套路和技巧偏多&#xff0c;還是那句話很多東西不經歷你就是不懂&#xff…

測試人員如何向開發人員準確清晰地描述問題?

測試人員向開發人員準確清晰地描述問題可以采取以下方法&#xff1a; 提供詳細的背景和上下文信息&#xff1a;描述問題發生的環境、前提條件和操作步驟&#xff0c;讓開發人員能夠了解問題出現的場景。明確問題的癥狀和表現&#xff1a;清楚地說明問題的具體表現&#xff0c;…

【Python】2. 基礎語法

常量和表達式 我們可以把 Python 當成一個計算器, 來進行一些算術運算. 注意: print 是一個 Python 內置的 函數, 這個稍后詳細介紹. 可以使用 - * / ( ) 等運算符進行算術運算. 先算乘除, 后算加減. 運算符和數字之間, 可以沒有空格, 也可以有多個空格. 但是一般習慣上寫一…

LDR6328芯片:智能家居時代的小家電充電革新者

在當今的智能家居時代&#xff0c;小家電的供電方式正變得越來越智能化和高效化。 利用PD&#xff08;Power Delivery&#xff09;芯片進行誘騙取電&#xff0c;為后端小家電提供穩定電壓的技術&#xff0c;正逐漸成為行業的新寵。在這一領域&#xff0c;LDR6328芯片以其出色的…

Qt下使用modbus-c庫實現PLC線圈/保持寄存器的讀寫

系列文章目錄 提示&#xff1a;這里是該系列文章的所有文章的目錄 第一章&#xff1a;Qt下使用ModbusTcp通信協議進行PLC線圈/保持寄存器的讀寫&#xff08;32位有符號數&#xff09; 第二章&#xff1a;Qt下使用modbus-c庫實現PLC線圈/保持寄存器的讀寫 文章目錄 系列文章目錄…

前端Vue3項目如何打包成Docker鏡像運行

將前端Vue3項目打包成Docker鏡像并運行包括幾個主要步驟&#xff1a;項目打包、編寫Dockerfile、構建鏡像和運行容器。下面是一個基本的流程&#xff1a; 1. 項目打包 首先&#xff0c;確保你的Vue3項目可以正常運行和打包。在項目根目錄下執行以下命令來打包你的Vue3項目&am…

nest.js使用nest-winston日志一

nest-winston文檔 nest-winston - npm 參考&#xff1a;nestjs中winston日志模塊使用 - 浮的blog - SegmentFault 思否 安裝 cnpm install --save nest-winston winstoncnpm install winston-daily-rotate-file 在main.ts中 import { NestFactory } from nestjs/core; im…

【5G 接口協議】GTP-U協議介紹

博主未授權任何人或組織機構轉載博主任何原創文章&#xff0c;感謝各位對原創的支持&#xff01; 博主鏈接 本人就職于國際知名終端廠商&#xff0c;負責modem芯片研發。 在5G早期負責終端數據業務層、核心網相關的開發工作&#xff0c;目前牽頭6G算力網絡技術標準研究。 博客…

mysql學習

查看glibc版本 ldd --version --mysql啟動失敗,嘗試啟動 1 查看錯誤日志,端口被占用,參數名寫錯,有不支持的參數 2 通過mysqld啟動 mysqld --default-filemy.cnf & 3 mysqld --no-defaults --basedir/user/local/mysql --datadir/data/mysql/3306/data/ --usermysql 4 str…

深入理解 Nginx 的負載均衡與反向代理

深入理解 Nginx 的負載均衡與反向代理 Nginx 是一個高性能的 HTTP 和反向代理服務器&#xff0c;也是一個 IMAP/POP3/SMTP 代理服務器。由于其出色的性能和靈活性&#xff0c;Nginx 已成為現代 web 架構中的重要組成部分&#xff0c;尤其是在處理高并發連接和大規模流量時。在…

找到數組的中間位置-1991-[簡單]

力扣 關鍵點 從題目中總結出公式 sum * 2 nums[i] total從左往右開始嘗試&#xff0c;尋找 i 位置滿足上面的公式&#xff0c;為什么從左開始&#xff0c;因為題目要求找到最左邊的一個用前綴和的概念來解&#xff0c;從左往右嘗試i位置的左邊所有數之和&#xff0c;右邊所有…

基礎小白快速入門Python------>模塊的作用和意義

模塊&#xff0c; 這個詞聽起來是如此的高大威猛&#xff0c;以至于萌新小白見了瑟瑟發抖&#xff0c;本草履蟲見了都直搖頭&#xff0c;好像聽上去很難的樣子&#xff0c;但是但是&#xff0c;年輕人&#xff0c;請聽本少年細細講述&#xff0c;他只是看起來很難&#xff0c;實…

GO-接口

1. 接口 在Go語言中接口&#xff08;interface&#xff09;是一種類型&#xff0c;一種抽象的類型。 interface是一組method的集合&#xff0c;接口做的事情就像是定義一個協議&#xff08;規則&#xff09;&#xff0c;只要一臺機器有洗衣服和甩干的功能&#xff0c;我就稱它…

【go語言開發】swagger安裝和使用

本文主要介紹go-swagger的安裝和使用&#xff0c;首先介紹如何安裝swagger&#xff0c;測試是否成功&#xff1b;然后列出常用的注釋和給出使用例子&#xff1b;最后生成接口文檔&#xff0c;并在瀏覽器上測試 文章目錄 安裝注釋說明常用注釋參考例子 文檔生成格式化文檔生成do…

C++從零開始的打怪升級之路(day39)

這是關于一個普通雙非本科大一學生的C的學習記錄貼 在此前&#xff0c;我學了一點點C語言還有簡單的數據結構&#xff0c;如果有小伙伴想和我一起學習的&#xff0c;可以私信我交流分享學習資料 那么開啟正題 今天分享的是關于模板的知識點 1.非類型模板參數 模板參數分為…

大模型生成,Open API調用

大模型是怎么生成結果的 通俗原理 其實&#xff0c;它只是根據上文&#xff0c;猜下一個詞&#xff08;的概率&#xff09;…… OpenAI 的接口名就叫【completion】&#xff0c;也證明了其只會【生成】的本質。 下面用程序演示【生成下一個字】。你可以自己修改 prompt 試試…

高并發下的 AtomicReference 性能陷阱

介紹 Java 提供了 AtomicInteger/AtomicLong 在并發編程里經常用到&#xff0c;它們封裝了對 int 和 long 的原子操作。 Java 還提供了 AtomicReference&#xff0c;用于對象引用做原子性的管理&#xff0c;比如 get、set、CAS。 一般情況下 AtomicInteger、AtomicLong 的性能…

mac新環境

1、maven 設置阿里云鏡像 打開Maven的settings.xml文件。找到<mirrors>標簽&#xff0c;如果沒有&#xff0c;可以手動添加。在<mirrors>標簽內部添加以下內容&#xff1a; <mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorO…

【C++】類的轉換函數

使用場景 C中當你創建了一個類&#xff0c;你想把這個類對象轉換成基本類型的函數。類對象->基本類型對象 原理 如下實例&#xff0c;設計一個分數類&#xff0c;實現分數轉換成double 浮點數的轉換函數。并在mian函數隱式調用。 #include<iostream> class Fractio…

6. 使用 Spring Boot進行開發(Developing with Spring Boot)

6. 使用 Spring Boot進行開發&#xff08;Developing with Spring Boot&#xff09; 本節詳細介紹了如何使用Spring Boot。它涵蓋考慮構建系統、自動配置以及如何運行應用程序等主題。我們還介紹一些 Spring Boot 最新做法。雖然 Spring Boot 沒有什么特別之處&#xff08;它只…