数据结构之栈(Java,C语言的实现)以及相关习题巩固
栈
概念以及代码实现
栈是仅限于在表尾进行插入和删除的线性表,它遵循先进后出,后进先出原则
- 所以可以在递归,判断回文,反转链表.......
代码实现部分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语言的实现)以及相关习题巩固的更多相关文章
- 天勤考研数据结构笔记—栈的C语言实现
栈的基本概念 栈的定义:栈是一种只能在一端进行插入或删除操作的线性表.其中允许进行插入或删除的一端称为栈顶(top).栈顶是由一个称为栈顶指针的位置指示器(其实就是一个变量,对于顺序栈,就是数组索引, ...
- 数据结构与抽象 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. ...
- 读书笔记:《数据结构与算法分析Java语言描述》
目录 第 3 章 表.栈和队列 3.2 表 ADT 3.2.1 表的简单数组实现 3.2.2 简单链表 3.3 Java Collections API 中的表 3.3.1 Collection 接口 ...
- 数据结构——栈(C语言实现)
#include <stdio.h> #include <stdlib.h> #include<string.h> #include<malloc.h> ...
- 《数据结构与算法分析-Java语言描述》 分享下载
书籍信息 书名:<数据结构与算法分析-Java语言描述> 原作名:Data Structures and Algorithm Analysis in Java 作者: 韦斯 (Mark A ...
- 数据结构(栈&堆 )
在计算机领域,堆栈是一个不容忽视的概念,堆栈是两种数据结构.堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除.在单片机应用中,堆栈是个特殊的存储区,主要功能 ...
- 栈-java代码
import java.util.Arrays; public class StackDemo { private int maxSize; private long[] stackArray; pr ...
- 大数据全栈式开发语言 – Python
前段时间,ThoughtWorks在深圳举办一次社区活动上,有一个演讲主题叫做“Fullstack JavaScript”,是关于用JavaScript进行前端.服务器端,甚至数据库(MongoDB) ...
- 不使用数据结构反转栈 递归 CVTE实习 CVTE是一家什么公司
本文因为垃圾csdn标题字限制,标题写不好.本文想说一个算法,和我在CVTE的实习,我看到CVTE是一家什么公司.如果想要喷我的,可以留言,我不会理.如果想喷公司,可以在博客评论或发到我邮件linde ...
- 为什么说Python 是大数据全栈式开发语言
欢迎大家访问我的个人网站<刘江的博客和教程>:www.liujiangblog.com 主要分享Python 及Django教程以及相关的博客 交流QQ群:453131687 原文链接 h ...
随机推荐
- vue 商品sku,笛卡尔算法,商品添加。动态生成table,table添加值后 再生成的table 不改变table之前输入的值
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 剑指offer05(Java)-替换空格(简单)
题目: 请实现一个函数,把字符串 s 中的每个空格替换成"%20". 示例 1: 输入:s = "We are happy."输出:"We%20are ...
- 力扣696(java)-计数二进制子串(简单)
题目: 给定一个字符串 s,统计并返回具有相同数量 0 和 1 的非空(连续)子字符串的数量,并且这些子字符串中的所有 0 和所有 1 都是成组连续的. 重复出现(不同位置)的子串也要统计它们出现的次 ...
- RocketMQ 消息集成:多类型业务消息-普通消息
简介: 本篇将从业务集成场景的诉求开始,介绍 RocketMQ 作为业务消息集成方案的核心能力和优势,通过功能场景.应用案例以及最佳实践等角度介绍 RocketMQ 普通消息类型的使用. 引言 Apa ...
- 阿里云架构师梁旭:MES on 云盒,助力客户快速构建数字工厂
简介: 四大优势:一站式交付.业务低延时.数据本地驻留.多工厂统一运维 2022年5月18日,在"云上数字工厂与中小企业数字化转型创新论坛"暨"鼎捷MES & 阿 ...
- 大数据时代下的App数据隐私安全
简介:随着信息技术快速发展,大数据为我们带来信息共享.便捷生活的同时,还存在着数据安全问题,主流商业模式下APP面临新的挑战.工信部持续开展APP侵权整治活动,进行了了六批次集中抽检,检查了76万款 ...
- ClickHouse Keeper 源码解析
简介:ClickHouse 社区在21.8版本中引入了 ClickHouse Keeper.ClickHouse Keeper 是完全兼容 Zookeeper 协议的分布式协调服务.本文对开源版本 C ...
- Dataphin功能:集成——如何将业务系统的数据抽取汇聚到数据中台
简介: 数据集成是简单高效的数据同步平台,致力于提供具有强大的数据预处理能力.丰富的异构数据源之间数据高速稳定的同步能力,为数据中台的建设打好坚实的数据基座. 数据中台是当下大数据领域最前沿的数据建 ...
- dotnet 在 WPF 里显示数学 π 的颜色
有逗比小伙伴问我,数学的 π 视觉效果是啥.于是我就来写一个逗比的应用将 π 的颜色在 WPF 应用画出来.原理就是读取 π 的小数点后的数值,然后使用逗比算法转换为 RGB 颜色像素,接着将这些像素 ...
- Petalinux 基本工程的构建
Petalinux 基本工程的构建 在上一节,我们安装好linux了,这一节,我们搭建一个简单的工程测试一下,并通过TF卡启动 电脑环境 vivado版本:2019.2 petalinux版本:201 ...