數據結構-C語言版本(三)棧

數據結構中的棧:概念、操作與實戰

第一部分 棧分類及常見形式

棧是一種遵循后進先出(LIFO, Last In First Out)原則的線性數據結構。棧主要有以下幾種實現形式:

1. 數組實現的棧(順序棧)

#define MAX_SIZE 100typedef struct {int data[MAX_SIZE];int top;
} ArrayStack;

2. 鏈表實現的棧(鏈式棧)

typedef struct StackNode {int data;struct StackNode* next;
} StackNode;typedef struct {StackNode* top;
} LinkedStack;

3. 動態擴容棧

當棧滿時能自動擴容的棧(基于數組實現)

typedef struct {int *data;int top;int capacity;
} DynamicStack;

4. 雙棧共享同一存儲空間

兩個棧共享一個數組空間,從兩端向中間生長

typedef struct {int data[MAX_SIZE];int top1;  // 棧1的棧頂指針int top2;  // 棧2的棧頂指針
} DoubleStack;

第二部分 棧常見操作

1. 初始化棧

// 初始化數組棧
void initArrayStack(ArrayStack *stack) {stack->top = -1;
}// 初始化鏈式棧
void initLinkedStack(LinkedStack *stack) {stack->top = NULL;
}// 初始化動態棧
void initDynamicStack(DynamicStack *stack, int initialCapacity) {stack->data = (int*)malloc(initialCapacity * sizeof(int));stack->top = -1;stack->capacity = initialCapacity;
}

2. 入棧操作

// 數組棧入棧
void pushArrayStack(ArrayStack *stack, int value) {if(stack->top >= MAX_SIZE - 1) {printf("棧已滿\n");return;}stack->data[++stack->top] = value;
}// 鏈式棧入棧
void pushLinkedStack(LinkedStack *stack, int value) {StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));newNode->data = value;newNode->next = stack->top;stack->top = newNode;
}// 動態棧入棧(帶自動擴容)
void pushDynamicStack(DynamicStack *stack, int value) {if(stack->top == stack->capacity - 1) {stack->capacity *= 2;stack->data = (int*)realloc(stack->data, stack->capacity * sizeof(int));}stack->data[++stack->top] = value;
}

3. 出棧操作

// 數組棧出棧
int popArrayStack(ArrayStack *stack) {if(stack->top == -1) {printf("棧為空\n");return -1; // 錯誤碼}return stack->data[stack->top--];
}// 鏈式棧出棧
int popLinkedStack(LinkedStack *stack) {if(stack->top == NULL) {printf("棧為空\n");return -1; // 錯誤碼}StackNode* temp = stack->top;int value = temp->data;stack->top = stack->top->next;free(temp);return value;
}

4. 查看棧頂元素

// 查看數組棧頂元素
int peekArrayStack(ArrayStack *stack) {if(stack->top == -1) {printf("棧為空\n");return -1;}return stack->data[stack->top];
}// 查看鏈式棧頂元素
int peekLinkedStack(LinkedStack *stack) {if(stack->top == NULL) {printf("棧為空\n");return -1;}return stack->top->data;
}

5. 判斷棧是否為空

// 判斷數組棧是否為空
int isEmptyArrayStack(ArrayStack *stack) {return stack->top == -1;
}// 判斷鏈式棧是否為空
int isEmptyLinkedStack(LinkedStack *stack) {return stack->top == NULL;
}

6. 獲取棧大小

// 獲取數組棧大小
int sizeArrayStack(ArrayStack *stack) {return stack->top + 1;
}// 獲取鏈式棧大小
int sizeLinkedStack(LinkedStack *stack) {int count = 0;StackNode* current = stack->top;while(current != NULL) {count++;current = current->next;}return count;
}

第三部分 棧編程題例子

1. 括號匹配檢查

int isValidParentheses(char* s) {char stack[10000];int top = -1;for(int i = 0; s[i] != '\0'; i++) {if(s[i] == '(' || s[i] == '[' || s[i] == '{') {stack[++top] = s[i];} else {if(top == -1) return 0;char topChar = stack[top--];if((s[i] == ')' && topChar != '(') ||(s[i] == ']' && topChar != '[') ||(s[i] == '}' && topChar != '{')) {return 0;}}}return top == -1;
}

2. 逆波蘭表達式求值

int evalRPN(char** tokens, int tokensSize) {int stack[10000];int top = -1;for(int i = 0; i < tokensSize; i++) {if(strcmp(tokens[i], "+") == 0) {int b = stack[top--];int a = stack[top--];stack[++top] = a + b;} else if(strcmp(tokens[i], "-") == 0) {int b = stack[top--];int a = stack[top--];stack[++top] = a - b;} else if(strcmp(tokens[i], "*") == 0) {int b = stack[top--];int a = stack[top--];stack[++top] = a * b;} else if(strcmp(tokens[i], "/") == 0) {int b = stack[top--];int a = stack[top--];stack[++top] = a / b;} else {stack[++top] = atoi(tokens[i]);}}return stack[top];
}

3. 用棧實現隊列

typedef struct {int inStack[MAX_SIZE];int outStack[MAX_SIZE];int inTop;int outTop;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue));queue->inTop = -1;queue->outTop = -1;return queue;
}void push(MyQueue* obj, int x) {obj->inStack[++obj->inTop] = x;
}int pop(MyQueue* obj) {if(obj->outTop == -1) {while(obj->inTop != -1) {obj->outStack[++obj->outTop] = obj->inStack[obj->inTop--];}}return obj->outStack[obj->outTop--];
}int peek(MyQueue* obj) {if(obj->outTop == -1) {while(obj->inTop != -1) {obj->outStack[++obj->outTop] = obj->inStack[obj->inTop--];}}return obj->outStack[obj->outTop];
}int empty(MyQueue* obj) {return obj->inTop == -1 && obj->outTop == -1;
}

4. 最小棧(能在O(1)時間內檢索到最小元素的棧)

typedef struct {int dataStack[MAX_SIZE];int minStack[MAX_SIZE];int top;
} MinStack;MinStack* minStackCreate() {MinStack* stack = (MinStack*)malloc(sizeof(MinStack));stack->top = -1;return stack;
}void minStackPush(MinStack* obj, int val) {obj->dataStack[++obj->top] = val;if(obj->top == 0) {obj->minStack[obj->top] = val;} else {obj->minStack[obj->top] = val < obj->minStack[obj->top-1] ? val : obj->minStack[obj->top-1];}
}void minStackPop(MinStack* obj) {obj->top--;
}int minStackTop(MinStack* obj) {return obj->dataStack[obj->top];
}int minStackGetMin(MinStack* obj) {return obj->minStack[obj->top];
}

5. 棧的壓入、彈出序列驗證

int validateStackSequences(int* pushed, int pushedSize, int* popped, int poppedSize) {if(pushedSize != poppedSize) return 0;int stack[pushedSize];int top = -1;int popIndex = 0;for(int i = 0; i < pushedSize; i++) {stack[++top] = pushed[i];while(top != -1 && stack[top] == popped[popIndex]) {top--;popIndex++;}}return top == -1;
}

6. 每日溫度(計算需要等待多少天才能得到更暖和的溫度)

int* dailyTemperatures(int* temperatures, int temperaturesSize, int* returnSize) {*returnSize = temperaturesSize;int* result = (int*)malloc(temperaturesSize * sizeof(int));memset(result, 0, temperaturesSize * sizeof(int));int stack[temperaturesSize];int top = -1;for(int i = 0; i < temperaturesSize; i++) {while(top != -1 && temperatures[i] > temperatures[stack[top]]) {int prevIndex = stack[top--];result[prevIndex] = i - prevIndex;}stack[++top] = i;}return result;
}

棧作為一種基礎而重要的數據結構,在編譯器設計、操作系統、算法實現等領域有廣泛應用。掌握棧的各種操作和典型應用場景,對于提升編程能力和算法思維至關重要。通過練習這些題目,可以深入理解棧的特性及其解決問題的思路。

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

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

相關文章

如何以特殊工藝攻克超薄電路板制造難題?

一、超薄PCB的行業定義與核心挑戰 超薄PCB通常指厚度低于1.0毫米的電路板&#xff0c;而高端產品可進一步壓縮至0.4毫米甚至0.2毫米以下。這類電路板因體積小、重量輕、熱傳導性能優異&#xff0c;被廣泛應用于折疊屏手機、智能穿戴設備、醫療植入器械及新能源汽車等領域。然而…

AI 賦能 3D 創作!Tripo3D 全功能深度解析與實操教程

大家好&#xff0c;歡迎來到本期科技工具分享&#xff01; 今天要給大家帶來一款革命性的 AI 3D 模型生成平臺 ——Tripo3D。 無論你是游戲開發者、設計師&#xff0c;還是 3D 建模愛好者&#xff0c;只要想降低創作門檻、提升效率&#xff0c;這款工具都值得深入了解。 接下…

如何理解抽象且不易理解的華為云 API?

API的概念在華為云的使用中非常抽象&#xff0c;且不容易理解&#xff0c;用通俗的語言 形象的比喻來講清楚——什么是華為云 API&#xff0c;怎么用&#xff0c;背后原理&#xff0c;以及主要元素有哪些&#xff0c;盡量讓新手也能明白。 &#x1f9e0; 一句話先理解&#xf…

第 7 篇:總結與展望 - 時間序列學習的下一步

第 7 篇&#xff1a;總結與展望 - 時間序列學習的下一步 (圖片來源: Guillaume Hankenne on Pexels) 恭喜你&#xff01;如果你一路跟隨這個系列走到了這里&#xff0c;那么你已經成功地完成了時間序列分析的入門之旅。我們從零開始&#xff0c;一起探索了時間數據的基本概念、…

PPT無法編輯怎么辦?原因及解決方法全解析

在日常辦公中&#xff0c;我們經常會遇到需要編輯PPT的情況。然而&#xff0c;有時我們會發現PPT文件無法編輯&#xff0c;這可能由多種原因引起。今天我們來看看PPT無法編輯的幾種常見原因&#xff0c;并提供實用的解決方法&#xff0c;幫助你輕松應對。 原因1&#xff1a;文…

前端面試題---GET跟POST的區別(Ajax)

GET 和 POST 是兩種 HTTP 請求方式&#xff0c;它們在傳輸數據的方式和所需空間上有一些重要區別&#xff1a; ? 一句話概括&#xff1a; GET 數據放在 URL 中&#xff0c;受限較多&#xff1b;POST 數據放在請求體中&#xff0c;空間更大更安全。 &#x1f4e6; 1. 所需空間…

第 5 篇:初試牛刀 - 簡單的預測方法

第 5 篇&#xff1a;初試牛刀 - 簡單的預測方法 經過前面四篇的學習&#xff0c;我們已經具備了處理時間序列數據的基本功&#xff1a;加載、可視化、分解以及處理平穩性。現在&#xff0c;激動人心的時刻到來了——我們要開始嘗試預測 (Forecasting) 未來&#xff01; 預測是…

從代碼學習深度學習 - 學習率調度器 PyTorch 版

文章目錄 前言一、理論背景二、代碼解析2.1. 基本問題和環境設置2.2. 訓練函數2.3. 無學習率調度器實驗2.4. SquareRootScheduler 實驗2.5. FactorScheduler 實驗2.6. MultiFactorScheduler 實驗2.7. CosineScheduler 實驗2.8. 帶預熱的 CosineScheduler 實驗三、結果對比與分析…

k8s 基礎入門篇之開啟 firewalld

前面在部署k8s時&#xff0c;都是直接關閉的防火墻。由于生產環境需要開啟防火墻&#xff0c;只能放行一些特定的端口&#xff0c; 簡單記錄一下過程。 1. firewall 與 iptables 的關系 1.1 防火墻&#xff08;Firewall&#xff09; 定義&#xff1a; 防火墻是網絡安全系統&…

RSS 2025|蘇黎世提出「LLM-MPC混合架構」增強自動駕駛,推理速度提升10.5倍!

論文題目&#xff1a;Enhancing Autonomous Driving Systems with On-Board Deployed Large Language Models 論文作者&#xff1a;Nicolas Baumann&#xff0c;Cheng Hu&#xff0c;Paviththiren Sivasothilingam&#xff0c;Haotong Qin&#xff0c;Lei Xie&#xff0c;Miche…

list的學習

list的介紹 list文檔的介紹 list是可以在常數范圍內在任意位置進行插入和刪除的序列式容器&#xff0c;并且該容器可以前后雙向迭代。list的底層是雙向鏈表結構&#xff0c;雙向鏈表中每個元素存儲在互不相關的獨立節點中&#xff0c;在節點中通過指針指向其前一個元素和后一…

生物信息學技能樹(Bioinformatics)與學習路徑

李升偉 整理 生物信息學是一門跨學科領域&#xff0c;涉及生物學、計算機科學以及統計學等多個方面。以下是關于生物信息學的學習路徑及相關技能的詳細介紹。 一、基礎理論知識 1. 生物學基礎知識 需要掌握分子生物學、遺傳學、細胞生物學等相關概念。 對基因組結構、蛋白質…

AOSP Android14 Launcher3——遠程窗口動畫關鍵類SurfaceControl詳解

在 Launcher3 執行涉及其他應用窗口&#xff08;即“遠程窗口”&#xff09;的動畫時&#xff0c;例如“點擊桌面圖標啟動應用”或“從應用上滑回到桌面”的過渡動畫&#xff0c;SurfaceControl 扮演著至關重要的角色。它是實現這些跨進程、高性能、精確定制動畫的核心技術。 …

超詳細實現單鏈表的基礎增刪改查——基于C語言實現

文章目錄 1、鏈表的概念與分類1.1 鏈表的概念1.2 鏈表的分類 2、單鏈表的結構和定義2.1 單鏈表的結構2.2 單鏈表的定義 3、單鏈表的實現3.1 創建新節點3.2 頭插和尾插的實現3.3 頭刪和尾刪的實現3.4 鏈表的查找3.5 指定位置之前和之后插入數據3.6 刪除指定位置的數據和刪除指定…

17.整體代碼講解

從入門AI到手寫Transformer-17.整體代碼講解 17.整體代碼講解代碼 整理自視頻 老袁不說話 。 17.整體代碼講解 代碼 import collectionsimport math import torch from torch import nn import os import time import numpy as np from matplotlib import pyplot as plt fro…

前端性能優化:所有權轉移

前端性能優化&#xff1a;所有權轉移 在學習rust過程中&#xff0c;學到了所有權概念&#xff0c;于是便聯想到了前端&#xff0c;前端是否有相關內容&#xff0c;于是進行了一些實驗&#xff0c;并整理了這些內容。 所有權轉移&#xff08;Transfer of Ownership&#xff09;…

Missashe考研日記-day23

Missashe考研日記-day23 0 寫在前面 博主前幾天有事回家去了&#xff0c;斷更幾天了不好意思&#xff0c;就當回家休息一下調整一下狀態了&#xff0c;今天接著開始更新。雖然每天的博客寫的內容不算多&#xff0c;但其實還是挺費時間的&#xff0c;比如這篇就花了我40多分鐘…

Docker 中將文件映射到 Linux 宿主機

在 Docker 中&#xff0c;有多種方式可以將文件映射到 Linux 宿主機&#xff0c;以下是常見的幾種方法&#xff1a; 使用-v參數? 基本語法&#xff1a;docker run -v [宿主機文件路徑]:[容器內文件路徑] 容器名稱? 示例&#xff1a;docker run -it -v /home/user/myfile.txt:…

HarmonyOS-ArkUI-動畫分類簡介

本文的目的是,了解一下HarmonyOS動畫體系中的分類。有個大致的了解即可。 動效與動畫簡介 動畫,是客戶端提升界面交互用戶體驗的一個重要的方式。可以使應用程序更加生動靈越,提高用戶體驗。 HarmonyOS對于界面的交互方面,圍繞回歸本源的設計理念,打造自然,流暢品質一提…

C++如何處理多線程環境下的異常?如何確保資源在異常情況下也能正確釋放

多線程編程的基本概念與挑戰 多線程編程的核心思想是將程序的執行劃分為多個并行運行的線程&#xff0c;每個線程可以獨立處理任務&#xff0c;從而充分利用多核處理器的性能優勢。在C中&#xff0c;開發者可以通過std::thread創建線程&#xff0c;并使用同步原語如std::mutex、…