【数据结构】11 堆栈(顺序存储和链式存储)

定义

可认为是具有一定约束的线性表,插入和删除操作都在一个称为栈顶的端点位置。也叫后入先出表(LIFO)
类型名称:堆栈(STACK)
数据对象集: 一个有0个或者多个元素的有穷线性表。
操作集
(1)Stack CreateStack( int MaxSize)
生成空堆栈,其最大长度为MaxSize
(2)bool IsFull(Stack)
判断栈S是否已满。
(3)bool Push(Stack S, ElementType X)
将元素X压入堆栈
(4)ElementType Pop(Stack S)
删除并返回栈顶元素

例3.5 如果将abcd四个字符按顺序压入堆栈,是否可能产生cabd这样的序列,共可能产生多少种输出?
一个字符出入栈:只可能是A进——A出
两个字符出入栈: 2种情况
A进A出 B进B出
A进B进 B出A出
三个字符出入栈: 5种情况
A进B进C进 C出B出A出
A进B进 B出 C进 C出
A进B进 B出A出 C进C出
A进A出 B进B出 C进C出
A进A出 B进C进 C出B出
四个字符: 14种情况

  1. A在第一位出 A_ _ _
    对应3个字符出入栈 -5种情况
  2. A在第二位 _ A _ _
    只能B出来后A才能出 BA_ _
    对应2个字符出入栈 -2种情况
  3. A在第三位 _ _ A _
    前两位必是 B或者C
    最后一位必是D
    2种情况
  4. A在第四位 _ _ _ A
    对应三个字符出入栈 5种情况

堆栈的实现

顺序栈的实现

由一个一维数组和一个记录栈顶元素位置的变量组成,另外还有一个记录堆栈最大容量的变量MaxSize。
习惯将栈底放在数组下标小的那端,栈顶位置用一个整型变量Top记录当前栈顶元素的下标值。当Top指向-1时,表示空栈;当Top指向MaxSize-1时表示栈满。
顺序栈类型Stack表示如下:

typedef int ElementType;
typedef int Position;
typedef struct SNode* PtrToSNode;struct SNode {ElementType* Data;Position Top;int MaxSize;};typedef PtrToSNode Stack;

顺序栈的创建

Stack CreateStack(int MaxSize) {Stack S = (Stack)malloc(sizeof(SNode) * 1);S->Data = (ElementType * )malloc(sizeof(ElementType) * MaxSize);S->Top = -1;S->MaxSize = MaxSize;return S;
}

进栈


bool IsFull(Stack S) {if (S->Top == S->MaxSize - 1) {return true;}return false;
}bool Push(Stack S, ElementType X) {if (IsFull(S)) {printf("The Stack is full!\n");return false;}(S->Top)++;S->Data[S->Top] = X;return true;}

出栈

bool IsEmpty(Stack S) {if (S->Top == -1) {return true;}return false;
}ElementType Pop(Stack S) {if (IsEmpty(S)) {printf("The Stack is empty!\n");return -1;}int temp = S->Data[S->Top];(S->Top)--;return temp;}

完整代码

# include <stdio.h>
#include < stdlib.h>typedef int ElementType;
typedef int Position;
typedef struct SNode* PtrToSNode;struct SNode {ElementType* Data;Position Top;int MaxSize;};typedef PtrToSNode Stack;Stack CreateStack(int MaxSize) {Stack S = (Stack)malloc(sizeof(SNode) * 1);S->Data = (ElementType * )malloc(sizeof(ElementType) * MaxSize);S->Top = -1;S->MaxSize = MaxSize;return S;
}bool IsFull(Stack S) {if (S->Top == S->MaxSize - 1) {return true;}return false;
}bool Push(Stack S, ElementType X) {if (IsFull(S)) {printf("The Stack is full!\n");return false;}/*(S->Top)++;S->Data[S->Top] = X;*/S->Data[++(S->Top)] = X;return true;}bool IsEmpty(Stack S) {if (S->Top == -1) {return true;}return false;
}ElementType Pop(Stack S) {if (IsEmpty(S)) {printf("The Stack is empty!\n");return -1;}/*int temp = S->Data[S->Top];(S->Top)--;return temp;*/return (S->Data[(S->Top)--]);}void print_s(Stack S) {int t = S->Top;while (t != -1) {printf("Node: %d\n", S->Data[t]);(t)--;}
}int main() {Stack S = NULL;int MaxSize = 10;S = CreateStack(MaxSize);ElementType X;int N;scanf_s("%d", &N);while (N--) {scanf_s("%d", &X);if (Push(S, X) == false) {printf("Push error!\n");}}print_s(S);int out = Pop(S);printf("out : %d\n", out);print_s(S);}

用一个数组实现两个堆栈

在这里插入图片描述

结构体
typedef struct DSNode* DStack;
struct DSNode
{ElementType* Data;Position Top1;Position Top2;int MaxSize;
};
创建
DStack CreateDStack(int MaxSize) {DStack S = (DStack)malloc(sizeof(DSNode) * 1);S->Data = (ElementType*)malloc(sizeof(ElementType) * MaxSize);S->Top2 = -1;S->Top1 = MaxSize;S->MaxSize = MaxSize;return S;
}
入栈

bool PushX(DStack S, ElementType X, int Tag) {if (S->Top1 - S->Top2 == 1) {printf("the stack is full!\n");return false;}if (Tag == 1) {(S->Top1)--;S->Data[S->Top1] = X;}else{(S->Top2)++;S->Data[S->Top2] = X;}return true;
}
出栈

ElementType PopX(DStack S, int Tag) {if (Tag == 1) {if (S->Top1 == S->MaxSize) {printf("the stack1 is empty!\n");return -1;}else {return S->Data[(S->Top1)++];}}else {if (S->Top2 == -1) {printf("the stack2 is empty!\n");return -1;}else {return S->Data[(S->Top2)--];}}}
完整代码
# include <stdio.h>
#include < stdlib.h>typedef int ElementType;
typedef int Position;typedef struct DSNode* DStack;
struct DSNode
{ElementType* Data;Position Top1;Position Top2;int MaxSize;
};DStack CreateDStack(int MaxSize) {DStack S = (DStack)malloc(sizeof(DSNode) * 1);S->Data = (ElementType*)malloc(sizeof(ElementType) * MaxSize);S->Top2 = -1;S->Top1 = MaxSize;S->MaxSize = MaxSize;return S;
}bool PushX(DStack S, ElementType X, int Tag) {if (S->Top1 - S->Top2 == 1) {printf("the stack is full!\n");return false;}if (Tag == 1) {(S->Top1)--;S->Data[S->Top1] = X;}else{(S->Top2)++;S->Data[S->Top2] = X;}return true;
}ElementType PopX(DStack S, int Tag) {if (Tag == 1) {if (S->Top1 == S->MaxSize) {printf("the stack1 is empty!\n");return -1;}else {return S->Data[(S->Top1)++];}}else {if (S->Top2 == -1) {printf("the stack2 is empty!\n");return -1;}else {return S->Data[(S->Top2)--];}}}void print_ds(DStack S) {printf("print S1:\n");int t = S->Top1;while (t != S->MaxSize) {printf("Node: %d\n", S->Data[t]);(t)++;}printf("print S2:\n");t = S->Top2;while (t != -1) {printf("Node: %d\n", S->Data[t]);(t)--;}
}int main() {int MAXSIZE = 10;DStack S = CreateDStack(MAXSIZE);ElementType X;int N;scanf_s("%d", &N);while (N--) {scanf_s("%d", &X);if (PushX(S, X, 1) == false) {printf("Push error!\n");}if (PushX(S, X, 2) == false) {printf("Push error!\n");}}print_ds(S);int out = PopX(S,1);printf("out : %d\n", out);print_ds(S);}

链式存储的实现

栈顶指针Top就是链表的栈顶结点,栈中的其他结点通过他们的指针Next链接起来,栈底结点的Next为NULL

数据结构

typedef int ElementType;
typedef struct SNode* PtrToSNode;struct SNode {ElementType Data;PtrToSNode Next;
};typedef PtrToSNode Stack;

创建


Stack CreateStack(Stack S) {S = (Stack)malloc(sizeof(SNode) * 1);S->Next = NULL;return S;
}

入栈


bool Push(Stack S, ElementType X) {Stack temp = (Stack)malloc(sizeof(SNode));temp->Data = X;temp->Next = S->Next;S->Next = temp;return true;}

出栈

ElementType Pop(Stack S) {if (S->Next == NULL) {printf("the stack is empty!\n");return -1;}ElementType re = S->Next->Data;S->Next = S->Next->Next;return re;}

完整代码

# include <stdio.h>
#include < stdlib.h>typedef int ElementType;
typedef struct SNode* PtrToSNode;struct SNode {ElementType Data;PtrToSNode Next;
};typedef PtrToSNode Stack;Stack CreateStack(Stack S) {S = (Stack)malloc(sizeof(SNode) * 1);S->Next = NULL;return S;
}bool Push(Stack S, ElementType X) {Stack temp = (Stack)malloc(sizeof(SNode));temp->Data = X;temp->Next = S->Next;S->Next = temp;return true;}ElementType Pop(Stack S) {if (S->Next == NULL) {printf("the stack is empty!\n");return -1;}ElementType re = S->Next->Data;S->Next = S->Next->Next;return re;}void prints(Stack S) {Stack t = S->Next;while (t != NULL) {printf("Node: %d\n", t->Data);t = t->Next;}
}int main() {Stack S = NULL;S = CreateStack(S);ElementType X;int N;scanf_s("%d", &N);while (N--) {scanf_s("%d", &X);if (Push(S, X) == false) {printf("Push error!\n");}}prints(S);ElementType out = Pop(S);printf("out : %d\n", out);prints(S);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/679110.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单片机与外设的交互

单片机与外设的交互是嵌入式系统中非常重要的一个基础知识点。单片机是一个集成在同一芯片上的中央处理器、存储器和输入/输出接口,它可以根据用户编写的程序与各种外部设备即外设进行交互。单片机与外设之间的交互主要通过单片机上的输入/输出口(I/O口)来实现。 I/O口的工作原…

一个适用于后渗透期间的信息收集工具

介绍 Pillager是一个适用于后渗透期间的信息收集工具&#xff0c;可以收集目标机器上敏感信息&#xff0c;方便下一步渗透工作的进行。 支持 注&#xff1a;✅表示经过测试&#xff0c;&#x1f6a7;表示理论上支持但未经测试&#xff0c;❌表示无此功能或不支持 后续将会陆续…

CSP-202006-1-线性分类器

CSP-202006-1-线性分类器 解题思路 通过比较第一个训练数据点的类别和直线函数值的正负来确定标准类别和标准函数值的正负。循环遍历训练数据中的每个点&#xff0c;计算直线函数值并与标准函数值比较&#xff0c;以确定该点所在的类别。 如果当前点的类别与标准类别一致&…

Lua: 一门轻量级、高效的脚本语言

Lua: 一门轻量级、高效的脚本语言 在当今软件开发的领域中&#xff0c;寻找一门既灵活又高效的脚本语言&#xff0c;一直是开发者们追求的目标。Lua作为一门小巧、高效、可嵌入的脚本语言&#xff0c;已经成为了众多开发者的首选之一。无论是游戏开发、嵌入式系统、Web 开发还是…

ncc匹配提速总结

我们ncc最原始的匹配方法是&#xff1a;学习模板w*h个像素都要带入ncc公式计算 第一种提速&#xff0c;学习模板是w*h&#xff0c;而我们支取其中的w/2*h/2,匹配窗口同理&#xff0c;计算量只有1/4。 另外一种因为ncc是线性匹配&#xff0c;我们在这上面也做了文章&#xff0…

《UE5_C++多人TPS完整教程》学习笔记2 ——《P3 多人游戏概念(Multiplayer Concept)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P3 多人游戏概念&#xff08;Multiplayer Concept&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&#xff08;也是译…

如何把手机平板变为电脑的屏幕

文章目录 安装软件运行效果结尾 本文首发地址 https://h89.cn/archives/181.html 最新更新地址 https://gitee.com/chenjim/chenjimblog 闲置的手机平板、触屏音箱等&#xff0c;均可作为电脑的扩展屏&#xff0c;为电脑增加一块显示屏&#xff0c;本文介绍如何使用免费的软件s…

DS Wannabe之5-AM Project: DS 30day int prep day12

Q1. Where is the confusion matrix used? Which module would you use to show it? 混淆矩阵 混淆矩阵常用于评估分类模型的性能&#xff0c;特别是在二分类或多分类问题中。它展示了实际类别与模型预测类别之间的关系。在Python中&#xff0c;可以使用sklearn.metrics模块…

代码随想录算法训练营DAY13 | 栈与队列 (3)

一、LeetCode 239 滑动窗口最大值 题目链接&#xff1a;239.滑动窗口最大值https://leetcode.cn/problems/sliding-window-maximum/ 思路&#xff1a;使用单调队列&#xff0c;只保存窗口中可能存在的最大值&#xff0c;从而降低时间复杂度。 public class MyQueue{Deque<I…

【闲谈】初识深度学习

在过去的十年中&#xff0c;深度学习彻底改变了我们处理数据和解决复杂问题的方式。从图像识别到自然语言处理&#xff0c;再到游戏玩法&#xff0c;深度学习的应用广泛且深入。本文将探讨深度学习的基础知识、关键技术以及最新的研究进展&#xff0c;为读者提供一个全面的视角…

第三节 zookeeper基础应用与实战2

目录 1. Watch事件监听 1.1 一次性监听方式&#xff1a;Watcher 1.2 Curator事件监听机制 2. 事务&异步操作演示 2.1 事务演示 2.2 异步操作 3. Zookeeper权限控制 3.1 zk权限控制介绍 3.2 Scheme 权限模式 3.3 ID 授权对象 3.4 Permission权限类型 3.5 在控制台…

Linux中孤儿/僵尸进程/wait/waitpid函数

孤儿进程&#xff1a; 概念&#xff1a;若子进程的父进程已经死掉&#xff0c;而子进程还存活着&#xff0c;这个进程就成了孤儿进程。 为了保证每个进程都有一个父进程&#xff0c;孤儿进程会被init进程领养&#xff0c;init进程成为了孤儿进程的养父进程&#xff0c;当孤儿…

DataBinding简易入门

简介 DataBinding是Google在18年推出的数据绑定框架&#xff0c;采用了MVVM模式来降低各模块之间代码的耦合度&#xff0c;使得整体代码逻辑设计更加清晰。众所周知&#xff0c;MVVM类似于MVC&#xff0c;主要目的是为分离View&#xff08;视图&#xff09;和Model&#xff08…

MATLAB知识点:isempty函数(★★★★☆)判断数组是否为空

​讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自第3章&#xff1a;课后习题讲解中拓展的函数 在讲解第…

OpenCV入门:图像处理的基石

在数字图像处理领域&#xff0c;OpenCV&#xff08;开源计算机视觉库&#xff09;是一个不可或缺的工具。它包含了一系列强大的算法和函数&#xff0c;使得开发者可以轻松地处理图像和视频数据。本文将带你走进OpenCV的世界&#xff0c;了解其基本概念和常见应用。 1. OpenCV简…

uniapp微信小程序开发踩坑日记:Pinia持久化

如果你使用过Pinia&#xff0c;那你应该知道Pinia持久化插件&#xff1a;https://prazdevs.github.io/pinia-plugin-persistedstate/zh/ 但由于官方文档提供的说明并不是针对小程序开发&#xff0c;所以我们在使用这个插件实现uniapp小程序开发中Pinia持久化会出现问题 我在C…

《统计学简易速速上手小册》第3章:概率分布与抽样技术(2024 最新版)

文章目录 3.1 重要的概率分布3.1.1 基础知识3.1.2 主要案例&#xff1a;顾客到访分析3.1.3 拓展案例 1&#xff1a;产品缺陷率分析3.1.4 拓展案例 2&#xff1a;日销售额预测 3.2 抽样方法与推断3.2.1 基础知识3.2.2 主要案例&#xff1a;顾客满意度调查3.2.2 拓展案例 1&#…

蓝桥杯每日一题------背包问题(二)

前言 本次讲解背包问题的一些延申问题&#xff0c;新的知识点主要涉及到二进制优化&#xff0c;单调队列优化DP&#xff0c;树形DP等。 多重背包 原始做法 多重背包的题意处在01背包和完全背包之间&#xff0c;因为对于每一个物品它规定了可选的个数&#xff0c;那么可以考虑…

【JavaEE】_HTML常用标签

目录 1.HTML结构 2. HTML常用标签 2.1 注释标签 2.2 标题标签&#xff1a;h1~h6 2.3 段落标签&#xff1a;p 2.4 换行标签&#xff1a;br 2.5 格式化标签 2.6 图片标签&#xff1a;img 2.7 超链接标签&#xff1a;a 2.8 表格标签 2.9 列表标签 2.10 表单标签 2.10…

C++继承(二):菱形继承、virtual菱形虚拟继承

目录 一、了解菱形继承 二、菱形继承的问题 三、虚拟继承virtual 3.1virtual 3.2虚拟继承解决数据冗余和二义性的原理 四、总结/继承和组合 一、了解菱形继承 单继承&#xff1a;一个子类只有一个直接父类时称这个继承关系为单继承 多继承&#xff1a;一个子类有两个或…