數據結構棧的實現(C語言)

棧的基本概念

????????棧是一種特殊的線性存儲結構,是一種操作受到限制的線性表,特殊體現在兩個地方:

? ? ? ? 1、元素進棧出棧的操作只能從同一端完成,另一端是封閉的,通常將數據進棧叫做入棧,壓棧等,出棧叫做彈棧、出棧等。

? ? ? ? 2、棧中無論存數據還是取數據,都必須遵循“先進后出”的原則,即最先入棧的元素最先出棧。以上圖為例,很容易可以看出是元素 1 最先入棧,然后依次是元素 2、3、4 入棧。在此基礎上,如果想取出元素 1,根據“先進后出”的原則,必須先依次將元素 4、3、2 出棧,最后才能輪到元素 1 出棧。?

?????????

????????由此我們可以對棧存儲結構下一個定義:棧是一種“只能從一端存取元素,且存取過程必須遵循‘先進后出’原則”的線性存儲結構。

????????棧就類似于彈夾,只能從一端壓入子彈,要取出子彈也只能對最上方的子彈進行操作,對應了棧先進后出,只能操作棧頂元素。

? ? ? ? 上述提到,棧本質上是操作受到限制的線性表,線性表主要有兩種:分別是數組和鏈表,所以棧有數組和鏈表兩種實現方式。

????????1.順序存儲的數組,優點: 節省空間,操作簡單,學習成本較低,易于理解。缺點: 棧的大小從一開始就固定了,不利于動態擴容。

????????2.非順序存儲的鏈表,優缺點:與數組棧正好相反。

? ? ? ? 棧的核心操作包括出棧,入棧,判空,訪問棧頂等,數組棧要比鏈表棧多一個判滿操作。

數組棧

? ? ? ? 下述代碼實現了棧的基本操作,包括出棧、入棧、判空、判滿、訪問棧頂。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
//數組棧要提前設置最大容量
#define max 20typedef struct
{//以int類型數據為例int data[max];int index;//棧頂地址
}stack;
//壓棧
bool stack_push(stack *sk,int data)
{//檢測空指針if(sk == NULL)return false;//檢測棧是否已滿if(sk->index == max - 1)return false;//更新棧頂地址sk->index++;//數據入棧sk->data[sk->index] = data;return true;
}
//彈棧
bool stack_pop(stack *sk)
{//檢測空指針if(sk == NULL)return false;//檢測棧是否已空if(sk->index < 0)return false;//更新棧頂地址,無需將后面的數據置0,因為操作受限制,無法訪問到后邊的下標。sk->index--;return true;
}
//返回棧頂元素
int stack_top(stack *sk)
{//檢測空指針if(sk == NULL)return false;//檢測棧是否已空if(sk->index < 0)return false;return sk->data[sk->index];
}
bool stack_full(stack *sk)
{if(sk == NULL)return false;return sk->index == max - 1 ? true : false;
}
//查看棧是否已空
bool stack_empty(stack *sk)
{//檢測空指針if(sk == NULL)return false;return sk->index < 0 ? true : false;
}int main(int argc, char const *argv[])
{//初始化棧,設置棧頂為-1stack sk;sk.index = -1;//逐個壓棧,查看棧頂元素for (int i = 0; i < 20; i++){stack_push(&sk,i + 1);printf("%d ",stack_top(&sk));}printf("\n");stack_full(&sk) ? printf("已滿\n") : printf("未滿\n");stack_empty(&sk) ? printf("空\n") : printf("非空\n");stack_pop(&sk) ? printf("彈棧成功\n") : printf("彈棧失敗\n");printf("此時棧頂元素為%d\n",stack_top(&sk));for (int i = 0; i < 20; i++){stack_pop(&sk) ? printf("彈棧成功\n") : printf("彈棧失敗\n");}stack_empty(&sk) ? printf("空\n") : printf("非空\n");return 0;
}

?運行結果如下

????????因為在中間進行了一次出棧,所以在循環中的最后一次彈棧時,棧已經空,進而彈棧失敗。??

鏈表棧

? ? ? ? 鏈表棧的存儲方式是鏈表,所以在實現棧之前需要先定義鏈表的基本操作,再實現棧。

? ? ? ? 下述代碼實現了棧的基本操作包括判空、出棧、入棧、訪問棧頂,鏈表棧不存在判滿操作,只有數組棧需要,因為鏈表并不存在滿的情況。

#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>typedef struct node
{__uint32_t data;struct node *next;
}Node;typedef struct 
{struct node *top;
}stack;
//定義鏈表的頭插法,首元結點就是棧頂,對應了入棧操作
void head_insert(Node *list,__uint32_t data)
{Node *new_node = (Node *)malloc(sizeof(Node));new_node->data = data;new_node->next = list->next;list->next = new_node;
}
//定義鏈表的頭刪法,首元結點就是棧頂,對應了出棧操作
void head_delete(Node *list)
{Node *tmp = list->next;list->next = list->next->next;free(tmp);
}
//入棧,調用頭插法
bool stack_push(stack *sk,__uint32_t data)
{if(sk->top == NULL)return false;head_insert(sk->top,data);return true;
}
//出棧,調用頭刪法
bool stack_pop(stack *sk)
{//判斷是否為空棧if(sk->top->next == NULL)return false;head_delete(sk->top);return true;
}
//訪問棧頂元素
int stack_top(stack *sk)
{//判斷是否為空棧if(sk->top->next == NULL)return -1;return sk->top->next->data;
}
//棧判空,也就是鏈表判空
bool stack_empty(stack *sk)
{return sk->top->next == NULL ? true : false;
}
//摧毀整個鏈表
void list_destroy(Node *list)
{Node *current = list;while (current){Node *tmp = current;current = current->next;free(tmp);}}int main(int argc, char const *argv[])
{//定義一個鏈表Node *list = (Node *)malloc(sizeof(Node));list->data = 0;list->next = NULL;//定義棧頂指針stack *sk = (stack *)malloc(sizeof(stack));sk->top = list;stack_empty(sk) ? printf("空\n") : printf("非空\n");for (int i = 0; i < 10; i++){stack_push(sk,i + 1);printf("%d ",stack_top(sk));}printf("\n");printf("棧頂元素為%d\n",stack_top(sk));stack_empty(sk) ? printf("空\n") : printf("非空\n");stack_pop(sk);printf("棧頂元素為%d\n",stack_top(sk));for (int i = 0; i < 10; i++)stack_pop(sk) ? printf("彈棧成功\n") : printf("彈棧失敗\n");stack_empty(sk) ? printf("空\n") : printf("非空\n");list_destroy(list);free(sk);return 0;
}

運行結果如下

? ? ? ? 因為在中間進行了一次出棧,所以在循環中的最后一次彈棧時,棧已經空,進而彈棧失敗。?

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

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

相關文章

【springboot】IDEA手動創建SpringBoot簡單工程(無插件)

大致步驟 創建Maven工程 引入依賴 提供啟動類 詳細教程 創建Maven工程 修改pom.xml文件 添加父節點 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.5.3</…

獨立開發第二周:構建、執行、規劃

一 第二周的獨立開發旅程落下帷幕。相較于第一周的適應&#xff0c;本周的核心詞是“聚焦”與“執行”。 目標非常明確&#xff1a;在產品開發上取得進展&#xff1b;在個人工作節奏上&#xff0c;將上周初步形成的框架進行實踐與固化。 同時&#xff0c;為至關重要的自媒體運營…

在YOLO-World中集成DeformConv、CBAM和Cross-Modal Attention模塊的技術報告

在YOLO-World中集成DeformConv、CBAM和Cross-Modal Attention模塊的技術報告 1. 引言 1.1 項目背景 目標檢測是計算機視覺領域的核心任務之一,而YOLO(You Only Look Once)系列算法因其出色的速度和精度平衡而廣受歡迎。YOLO-World是YOLO系列的最新發展,專注于開放詞匯目標…

從UI設計到數字孿生實戰應用:構建智慧金融的風險評估與預警平臺

hello寶子們...我們是艾斯視覺擅長ui設計、前端開發、數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩!一、引言&#xff1a;傳統金融風控的 “滯后困境” 與數字孿生的破局之道金融風險的隱蔽性、突…

【Linux】權限相關指令

前言&#xff1a; 上兩篇文章我們講到了&#xff0c;關于Linux中的基礎指令。 【Linux】初見&#xff0c;基礎指令-CSDN博客【Linux】初見&#xff0c;基礎指令&#xff08;續&#xff09;-CSDN博客 本文我們來講Linux中關于權限中的一些指令 shell命令 Linux嚴格來說是一個操…

前端學習3--position定位(relative+absolute+sticky)

繼上一篇&#xff0c;做下拉菜單的時候&#xff0c;涉及到了position&#xff0c;這篇就來學習下~先看下position在下拉菜單中的應用&#xff1a;一、關鍵代碼回顧&#xff1a;/* 下拉菜單容器 */ .dropdown {position: relative; /* ? 關鍵父級 */ }/* 下拉內容&#xff08;默…

APP Inventor使用指南

APP Inventor使用指南一、組件介紹二、邏輯設計設計方法&#xff1a;設計實例&#xff08;參考嘉立創教程&#xff09;點擊跳轉 &#xff1a; app inventor&#xff08;點不開的話需要&#x1fa84;&#x1fa84;&#x1fa84;&#x1fa84;&#x1fa84;&#xff09; 一、組…

SpringAI實現保存聊天記錄到redis中

redis相關準備添加依賴我利用redission來實現<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.37.0</version> </dependency>添加配置文件spring:redis:database: 5host: 127.0.0.1…

Unity中使用EzySlice實現模型切割與UV控制完全指南

引言 在Unity中實現3D模型的動態切割是一個常見的需求&#xff0c;無論是用于游戲特效、建筑可視化還是醫療模擬。本文將全面介紹如何使用EzySlice插件實現高效的模型切割&#xff0c;并深入探討如何通過Shader Graph精確控制切割面的UV映射。 第一部分&#xff1a;EzySlice基…

【c++學習記錄】狀態模式,實現一個登陸功能

狀態模式建議為對象的所有可能狀態新建一個類&#xff0c; 然后將所有狀態的對應行為抽取到這些類中。 原始對象被稱為上下文 &#xff08;context&#xff09;&#xff0c; 它并不會自行實現所有行為&#xff0c; 而是會保存一個指向表示當前狀態的狀態對象的引用&#xff0c;…

Docker 搭建 Harbor 私有倉庫

1 部署 Harbor 注意&#xff1a;docker、docker-compose、Harbor的版本是否適配&#xff0c;這里使用的版本如下表&#xff1a; Docker版本Docker Compose版本Harbor版本v19.09.8v1.29.2v2.8.2 1.1 安裝 docker-compose # 下載 docker-compose 1.29.2 版本 curl -L "h…

C++類模板繼承部分知識及測試代碼

目錄 0.前言 1.類模板基本使用 2.類模板繼承 2.1類模板繼承過程中的模板參數 情況1&#xff1a;父類非模板&#xff0c;子類為模板 情況2&#xff1a;父類模板&#xff0c;子類為非模板 情況3&#xff1a;父類模板&#xff0c;子類為模板 3.STL中的模板類分析 3.1STL中…

Laravel + Python 圖片水印系統:實現與調試指南

前言 本系統通過 Laravel 作為前端框架接收用戶上傳的圖片&#xff0c;調用 Python 腳本處理水印添加&#xff0c;最終返回處理后的圖片。這種架構充分利用了 Laravel 的便捷性和 Python 圖像處理庫的強大功能。 一、Python 水印處理腳本 from PIL import Image, ImageEnhance …

【速通RAG實戰:企業應用】25、從數智化場景看RAG:是臨時方案,還是終局架構?

引言&#xff1a;RAG為何成為數智化場景的"必爭之地"&#xff1f; 當ChatGPT在2023年掀起生成式AI浪潮時&#xff0c;一個矛盾逐漸凸顯&#xff1a;大語言模型&#xff08;LLM&#xff09;能生成流暢文本&#xff0c;卻常陷入"幻覺"&#xff08;虛構事實&a…

[Python] -實用技巧篇1-用一行Python代碼搞定日常任務

在日常開發或數據處理過程中,我們常常為了一些簡單的小任務寫出數行代碼。但實際上,Python 提供了大量強大且簡潔的語法糖和標準庫工具,讓你用“一行代碼”輕松搞定復雜操作。 本文將通過多個典型場景展示如何用“一行 Python 代碼”高效完成常見任務。 一、文件操作:快速…

單細胞入門(1)——介紹

一、單細胞轉錄組測序流程介紹 單細胞測序能夠探索復雜組織中單個細胞的不同生物學特性&#xff0c;幫助我們認識細胞與細胞之間的差異。這些檢測方法有助于研究細胞譜系、細胞功能、細胞分化、細胞增殖和細胞應答&#xff0c;提升我們對復雜生物系統的理解&#xff0c;包括腫…

數據結構與算法之美:跳表

Hello大家好&#xff01;很高興我們又見面啦&#xff01;給生活添點passion&#xff0c;開始今天的編程之路&#xff01; 我的博客&#xff1a;<但凡. 我的專欄&#xff1a;《編程之路》、《數據結構與算法之美》、《題海拾貝》、《C修煉之路》 歡迎點贊&#xff0c;關注&am…

從0設計一個短鏈接服務:如何實現盡可能短、可變長的短網址系統?

從 0 設計一個短鏈接服務&#xff1a;如何實現盡可能短、可變長的短網址系統&#xff1f; 在日常生活中&#xff0c;我們經常在短信、微博、廣告營銷中看到“短鏈接”&#xff0c;如&#xff1a; https://t.cn/EXaQ4xY https://bit.ly/3Yp9zJk相比冗長復雜的原始 URL&#xff0…

Microsoft Word 中 .doc 和 .docx 的區別

Microsoft Word 中 .doc 和 .docx 的區別 解釋 Microsoft Word 中 .doc 和 .docx 文件格式的區別。這些格式都是 Word 處理文檔的標準&#xff0c;但它們在結構、兼容性和功能上存在顯著差異。下面我將詳細說明。 1. 基本定義 .doc&#xff1a;這是 Microsoft Word 的舊格式&am…

Springboot aop面向切面編程

aop:面向切面編程&#xff0c;理解在一個流程中插入一個切面&#xff0c;這樣切面方法會在指定位置執行能無影響的在某些方法前或者后插入一些動作springboot使用1.引入依賴<dependency><groupId>org.springframework.boot</groupId><artifactId>sprin…