概念以及代码实现

栈是仅限于在表尾进行插入和删除的线性表,它遵循先进后出,后进先出原则

  • 所以可以在递归,判断回文,反转链表.......

代码实现部分java

public interface Stack_i <T>{
//入栈
void push(T e);
//出栈
T pop();
//获取栈顶元素
T peek();
//获取栈的元素个数
int size();
//栈是否为空
boolean isEmpty();
}
import java.util.Random;
public class MyArr<T> { private int capacity = 0;
private int size = 0;
private T[] arr; public MyArr(int capacity) {
if (capacity < 0) this.capacity = 10; //if no right input, we will initial capacity 10
this.capacity = capacity;
this.arr = (T[]) new Object[capacity];
} public int getCapacity() {
return capacity;
} public int getSize() {
return size;
} public T[] setCapacity(int capacity) {
if (capacity < 0) {
throw new RuntimeException("扩大小异常");
}
this.capacity = capacity;
T[] newNum = (T[]) new Object[capacity];
for (int i = 0; i < this.size; ++i) {
newNum[i] = this.arr[i];
}
return newNum;
} //增加元素
public void add(T val) {
if (this.size >= this.capacity) {
this.arr = setCapacity(2 * this.capacity);
}
this.arr[this.size++] = val;
}
//数组末尾增加元素
public void addLst(T val){
this.add(val);
} //删除元素
public T removeByIndex(int index) {
if (index < 0 || index > this.capacity) {
throw new RuntimeException("数组越界");
}
for (int i = index; i < size - 1; ++i) {
arr[i] = arr[i + 1];
}
size--;
if (size < this.capacity / 4 && this.capacity > 4) {
arr = setCapacity(this.capacity / 4);
}
return this.arr[index];
}
//删除数组末尾元素
public T removeLast(){
return this.removeByIndex(this.size-1);
}
//修改位置元素
public void modify(int index, T val) {
if (index < 0 || index > size - 1) {
throw new RuntimeException("数组越界");
}
arr[index] = val;
} //获取某元素位置
public int locateVal(T val) {
for (int i = 0; i < size; ++i) {
if (arr[i] == val) {
return i;//return index
}
}
// if no find return -1
return -1;
}
//获取尾元素
public T getLast(){
return this.arr[this.size-1];
}
//打印元素 @Override
public String toString() {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append('[');
for (int i = 0; i < this.size - 1; ++i) {
stringBuffer.append(arr[i] + ",");
}
if(size>0) stringBuffer.append(arr[size - 1]);
stringBuffer.append(']');
return stringBuffer.toString();
} }
public class StackImplement<T> implements Stack_i<T>{

    private MyArr<T> data;
private int size=0;
@Override
public void push(T e) {
this.size++;
this.data.addLst(e);
} public StackImplement() {
data = new MyArr<>(10);
} @Override
public T pop() {
if(this.isEmpty()){
throw new RuntimeException("栈为空");
}
return this.data.removeLast();
} @Override
public T peek() {
return this.data.getLast();
} @Override
public int size() {
return this.size;
} @Override
public boolean isEmpty() {
if(size==0)return true;
return false;
}
public int getCapacity(){
return this.data.getCapacity();
}
}

c语言实现(顺序栈)

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define OVERFLOW 0
#define MAXSIZE 10
typedef int Status;
typedef int Element; //声明栈的顺序结构定义
typedef struct {
Element* base;
Element* top;
int stackSize;
}SqStack;
//栈的功能
Status InitStack(SqStack* S);//初始化栈
Status Push(SqStack* S, Element e);//入栈操作
Status Pop(SqStack* S, Element* e);//出栈操作,并返回出去的值
Status IsEmpty(SqStack S);//判断栈是否为空
void PrintStack(SqStack S);//打印栈
Status OperateMenu();//用户界面选择
Element GetTop(SqStack S);//获取头元素
void DestroyStack(SqStack* S);//销毁链表
Status ClearStack(SqStack* S);//清理栈中元素
int StackLen(SqStack S);//获取栈长度 int main() {
SqStack S;
/*
赋值为NULL,确保变量具有一个初始状态,避免出现潜在问题,如果没有初始化,
系统会分配一个随机地址,在后面对指针修改访问时可能会程序崩溃
*/
S.base = NULL;
S.top = NULL;
S.stackSize = 0;
int choice;//记录用户选择
Element e;//元素类型
int temp = 0;//接受函数返回值
int len;//获取栈长度
while (OK) {
choice = OperateMenu();
switch (choice)
{
case 1:
InitStack(&S);
printf("初始化栈\n");
break;
case 2:
printf("请输入要入栈的元素\n");
scanf("%d", &e);
temp = Push(&S, e);
if(temp==-1){
printf("此栈未被初始化!\n");
break;
}
printf("入栈成功!\n");
PrintStack(S);//打印元素
break; case 3:
temp = Pop(&S, &e);
if(temp==-1){
printf("此栈未被初始化!\n");
break;
}
if (temp == ERROR) {
printf("栈空!\n");
break;
}
printf("出栈的元素为:%d\n", e);
PrintStack(S);
break; case 4:
temp = IsEmpty(S);
if(temp==-1){
printf("此栈未被初始化!\n");
break;
}
if (temp == ERROR) {
printf("不为空栈!\n");
PrintStack(S);
break;
}
printf("为空栈\n");
break;
case 5:
PrintStack(S);
break;
case 6:
e = GetTop(S);
if(e==-2){
printf("此栈未被初始化!\n");
break;
}
if (e == -1) {
printf("为空栈\n");
break;
}
printf("栈顶元素为: %d\n", e);
PrintStack(S);
break;
case 7:
temp = ClearStack(&S);
if(temp==-1){
printf("此栈未被初始化!\n");
break;
}
printf("清理成功!\n");
break;
case 8:
len = StackLen(S);
if(len == -1){
printf("此栈未被初始化!\n");
break;
}
printf("链表长度为:%d\n", len);
PrintStack(S);
break;
case 9:
DestroyStack(&S);
printf("销毁成功\n");
break;
default:
exit(OVERFLOW);
} }
return 0;
}
Status InitStack(SqStack* S) {
S->base = (Element*)malloc(sizeof(Element) * MAXSIZE);
if (S->base == NULL) {
exit(OVERFLOW);//申请失败,异常结束程序
}
S->top = S->base;
S->stackSize = MAXSIZE;
//申请成功
return OK;
}
Status Push(SqStack* S,Element e) {
//判断栈是否初始化
if(S->top==NULL||S->base==NULL){
printf("此栈未被初始化!\n");
return -1;
}
//判断栈是否满
if (S->top - S->base == S->stackSize) {
S->base = (Element*)realloc(S->base, sizeof(Element) * MAXSIZE);
S->stackSize += MAXSIZE;
S->top = S->base + MAXSIZE;
}
*(S->top) = e;
S->top++;
//插入完毕
return OK;
}
Status Pop(SqStack* S, Element* e) {
if(S->top==NULL||S->base==NULL)return -1;//此栈未被初始化
if (S->top == S->base)return ERROR;//此时为空栈
*e = *(--S->top);
//出栈成功
return OK;
}
Status IsEmpty(SqStack S) {
if(S.top==NULL||S.base==NULL)return -1;//此栈未被初始化
if (S.base == S.top)return OK;//判断空栈
else return ERROR;
}
void PrintStack(SqStack S) {
if(S.top==NULL||S.base==NULL){
printf("此栈未被初始化\n");
return;//此栈未被初始化
}
if (S.base == S.top) {
printf("此栈为空栈\n");
return;
} Element* ptr = --S.top;
while (ptr!=S.base) {
printf("%d\t", *ptr);
--ptr;
}
//打印栈底元素
printf("%d", *S.base);
printf("\n");
return;
}
Status OperateMenu() {
int choice = 0;//记录用户选择
printf("----------------欢迎使用栈----------------\n");
printf("----------------1.初始化栈----------------\n");
printf("----------------2.入栈操作----------------\n");
printf("----------------3.出栈操作----------------\n");
printf("----------------4.判断栈是否为空----------\n");
printf("----------------5.打印栈------------------\n");
printf("----------------6.获取头元素--------------\n");
printf("----------------7.清空列表元素------------\n");
printf("----------------8.获取栈的长度------------\n");
printf("----------------9.销毁栈------------------\n");
printf("----------------10.退出--------------------\n");
printf("----------------请输入选项----------------\n");
scanf("%d", &choice);
return choice; }
Element GetTop(SqStack S) {
if(S.top==NULL||S.base==NULL)return -2;//此栈未被初始化
if (S.base == S.top) return -1;
return *(--S.top);
}
void DestroyStack(SqStack* S) {
S->base = NULL;
S->top = NULL;
S->stackSize = 0;
}
Status ClearStack(SqStack* S) {
if(S->top==NULL||S->base==NULL)return -1;//此栈未被初始化
if (S->top == S->base)return ERROR;//空表
S->top = S->base;
return OK;
}
int StackLen(SqStack S) {
if(S.top==NULL||S.base==NULL)return -1;//此栈未被初始化
return S.top - S.base;
}

例题

232. 用栈实现队列

1614. 括号的最大嵌套深度

给定 有效括号字符串 s,返回 s嵌套深度。嵌套深度是嵌套括号的 最大 数量。

示例 1:

输入:s = "(1+(2*3)+((8)/4))+1"

输出:3

解释:数字 8 在嵌套的 3 层括号中。

示例 2:

输入:s = "(1)+((2))+(((3)))"

输出:3

解释:数字 3 在嵌套的 3 层括号中。

示例 3:

输入:s = "()(())((()()))"

输出:3

提示:

  • 1 <= s.length <= 100
  • s 由数字 0-9 和字符 '+''-''*''/''('')' 组成
  • 题目数据保证括号字符串 s有效的括号字符串
java

class Solution {
public int maxDepth(String s) {
// 使用top表示栈顶指针
int top = 0;
// 记录括号数量
int res = 0;
for (int i = 0; i < s.length(); ++i) {
// 如果碰见左括号说明 括号深度增加 即入栈
if (s.charAt(i) == '(') {
++top;
// 记录最大深度
if (top > res) {
res = top;
}
// 碰到右括号出栈 深度就减少
} else if (s.charAt(i) == ')') {
--top;
}
}
return res;
}
}

234. 回文链表

给你一个单链表的头节点 head ,请你判断该链表是否为

回文链表

。如果是,返回 true ;否则,返回 false

示例 1:

输入:head = [1,2,2,1]
输出:true

示例 2:

输入:head = [1,2]
输出:false

提示:

  • 链表中节点数目在范围[1, 105]
  • 0 <= Node.val <= 9

进阶:你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
// 利用栈的先进后出原则
/*
可以把链表节点都入栈 然后逐一出栈 栈底指针与栈顶指针对比元素即可
*/
int[] stack = new int[100001];
int base = 0;
int top = 0;
ListNode p = head;
while (p != null) {
stack[top++] = p.val;
p = p.next;
}
--top;
while(base<=top){
if(stack[base]!=stack[top])return false;
base = base+1;
top = top-1;
}
return true;
}
}

1614. 括号的最大嵌套深度

LCR 123. 图书整理 I

206. 反转链表

402. 移掉 K 位数字

844. 比较含退格的字符串

LCR 036. 逆波兰表达式求值

[面试题 03.01. 三合一](

数据结构之栈(Java,C语言的实现)以及相关习题巩固的更多相关文章

  1. 天勤考研数据结构笔记—栈的C语言实现

    栈的基本概念 栈的定义:栈是一种只能在一端进行插入或删除操作的线性表.其中允许进行插入或删除的一端称为栈顶(top).栈顶是由一个称为栈顶指针的位置指示器(其实就是一个变量,对于顺序栈,就是数组索引, ...

  2. 数据结构与抽象 Java语言描述 第4版 pdf (内含标签)

    数据结构与抽象 Java语言描述 第4版 目录 前言引言组织数据序言设计类P.1封装P.2说明方法P.2.1注释P.2.2前置条件和后置条件P.2.3断言P.3Java接口P.3.1写一个接口P.3. ...

  3. 读书笔记:《数据结构与算法分析Java语言描述》

    目录 第 3 章 表.栈和队列 3.2 表 ADT 3.2.1 表的简单数组实现 3.2.2 简单链表 3.3 Java Collections API 中的表 3.3.1 Collection 接口 ...

  4. 数据结构——栈(C语言实现)

    #include <stdio.h> #include <stdlib.h> #include<string.h> #include<malloc.h> ...

  5. 《数据结构与算法分析-Java语言描述》 分享下载

    书籍信息 书名:<数据结构与算法分析-Java语言描述> 原作名:Data Structures and Algorithm Analysis in Java 作者: 韦斯 (Mark A ...

  6. 数据结构(栈&堆 )

    在计算机领域,堆栈是一个不容忽视的概念,堆栈是两种数据结构.堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除.在单片机应用中,堆栈是个特殊的存储区,主要功能 ...

  7. 栈-java代码

    import java.util.Arrays; public class StackDemo { private int maxSize; private long[] stackArray; pr ...

  8. 大数据全栈式开发语言 – Python

    前段时间,ThoughtWorks在深圳举办一次社区活动上,有一个演讲主题叫做“Fullstack JavaScript”,是关于用JavaScript进行前端.服务器端,甚至数据库(MongoDB) ...

  9. 不使用数据结构反转栈 递归 CVTE实习 CVTE是一家什么公司

    本文因为垃圾csdn标题字限制,标题写不好.本文想说一个算法,和我在CVTE的实习,我看到CVTE是一家什么公司.如果想要喷我的,可以留言,我不会理.如果想喷公司,可以在博客评论或发到我邮件linde ...

  10. 为什么说Python 是大数据全栈式开发语言

    欢迎大家访问我的个人网站<刘江的博客和教程>:www.liujiangblog.com 主要分享Python 及Django教程以及相关的博客 交流QQ群:453131687 原文链接 h ...

随机推荐

  1. DM 传统行业SQL优化案例

    来OB这么久还没有接触啥金融的SQL,只能发点其他行业的数据库SQL优化案例. 今天拿到手的这个案例SQL 传统行业的,很奇葩的SQL,表设计三范式都没弄好. 什么医疗,交通,能源这些传统行业的业务设 ...

  2. 力扣594(java&python)-最长和谐子序列(简单)

    题目: 和谐数组是指一个数组里元素的最大值和最小值之间的差别 正好是 1 . 现在,给你一个整数数组 nums ,请你在所有可能的子序列中找到最长的和谐子序列的长度. 数组的子序列是一个由数组派生出来 ...

  3. 牛客网-SQL专项训练15

    ①MySQL是一种(关系型)数据库管理系统. 关系型数据库的代表包括Oracle, Sql Server, MySQL. ②小李在创建完一张数据表后,发现少创建了一列,此时需要修改表结构,应该用哪个语 ...

  4. 阿里云CDN产品经理陈章炜:边缘创新技术和落地实践

    简介: CDN除了加速外,不断被赋予更多价值.在阿里云CDN推出的<极速奔跑吧 2021>首场直播中,阿里云架构师和产品经理不仅对近期阿里云发布的CDN产品最佳实践图进行了详细解读,还对C ...

  5. 如何快速调度 PTS 的百万并发能力

    ​简介:压测是通过模拟用户行为对业务系统发起请求,测算出系统的承载能力,并对系统做一次全面的体检,压测后可根据压测表现优化系统瓶颈,防止出现线上故障. 作者:灵苒 在实际的业务场景中,压测是必不可少的 ...

  6. 如何避免出现SQL注入漏洞

    ​简介: 本文将针对开发过程中依旧经常出现的SQL编码缺陷,讲解其背后原理及形成原因.并以几个常见漏洞存在形式,提醒技术同学注意相关问题.最后会根据原理,提供解决或缓解方案. ​ 作者 | 阿里云安全 ...

  7. Roslyn 将构建时间写入到输出文件

    我期望在每次构建完成之后,创建一个文件,在这个文件里面写入是什么时间构建的.这个需求实现非常简单,只需要使用 Target 在构建完成,使用 WriteLinesToFile 方法写入时间到输出文件即 ...

  8. WPF 已知问题 某些设备上的应用在 WindowChromeWorker 抛出 System.OverflowException 异常

    准确来说,这个不算是 WPF 的问题,而是系统等的问题.在某些设备上的使用了 WindowChrome 功能的 WPF 应用,将在运行过程,在 WindowChromeWorker 类里面抛出 Sys ...

  9. Rancher管理K8s集群(14)

    一.Rancher介绍 1.1 Rancher简介 Rancher 是一个开源的企业级多集群 Kubernetes 管理平台,实现了 Kubernetes 集群在混合云+本地 数据中心的集中部署与管理 ...

  10. LVGL学习资料

    一.资料整理 官网:https://lvgl.io/ 使用手册: 官方的使用手册是英文版的,百问网将其翻译成中文版的文档.地址如下: 官方使用文档:https://docs.lvgl.io/maste ...