数据结构栈(C语言Java语言的实现)相关习题

news2025/1/17 0:11:59

文章目录

    • 概念以及代码实现
    • 例题
      • [232. 用栈实现队列](https://leetcode.cn/problems/implement-queue-using-stacks/)
      • [1614. 括号的最大嵌套深度](https://leetcode.cn/problems/maximum-nesting-depth-of-the-parentheses/)
      • [234. 回文链表](https://leetcode.cn/problems/palindrome-linked-list/)
      • [1614. 括号的最大嵌套深度](https://leetcode.cn/problems/maximum-nesting-depth-of-the-parentheses/)
      • [LCR 123. 图书整理 I](https://leetcode.cn/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/)
      • [206. 反转链表](https://leetcode.cn/problems/reverse-linked-list/)
      • [402. 移掉 K 位数字](https://leetcode.cn/problems/remove-k-digits/)
      • [844. 比较含退格的字符串](https://leetcode.cn/problems/backspace-string-compare/)
      • [LCR 036. 逆波兰表达式求值](https://leetcode.cn/problems/8Zf90G/)
      • [面试题 03.01. 三合一](

概念以及代码实现

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

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

image-20240530132703003

代码实现部分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:

img

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

示例 2:

img

输入: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. 三合一](

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

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

相关文章

WiFi串口服务器与工业路由器:局域网应用的协同之力

在工业物联网&#xff08;IIoT&#xff09;迅猛发展的当下&#xff0c;局域网&#xff08;LAN&#xff09;作为连接工业设备与数据中心的桥梁&#xff0c;其重要性日益凸显。WiFi串口服务器与工业路由器作为局域网中的关键组件&#xff0c;以其独特的性能和功能&#xff0c;为传…

音视频开发—H265相关概念和压缩原理详解(GOP、宏块、帧内压缩、帧间压缩)

文章目录 1.什么是GOP&#xff1f;1.1 GOP介绍1.2.GOP中I帧/B帧/P帧1.3.I帧和IDR的区别联系I帧&#xff08;Intra Frame&#xff09;IDR帧&#xff08;Instantaneous Decoding Refresh Frame&#xff09;区别总结 1.4 帧与分组的关系1.5 SPS与PPSSPS&#xff08;Sequence Param…

02-CSS3基本样式

目录 1. CSS3简介 1.1 CSS3的兼容情况 1.2 优雅降级和渐进增强的开发思想 2. 新增选择器 2.1 选择相邻兄弟 2.2 匹配选择器 2.3 属性选择器(重点) 2.4 结构性伪类选择器&#xff08;重点&#xff09; 2.4.1 整体结构类型 2.4.2 标签结构类型 2.4.3 指定子元素的序号&…

Python——Selenium快速上手+方法(一站式解决问题)

目录 前言 一、Selenium是什么 二、Python安装Selenium 1、安装Selenium第三方库 2、下载浏览器驱动 3、使用Python来打开浏览器 三、Selenium的初始化 四、Selenium获取网页元素 4.1、获取元素的实用方法 1、模糊匹配获取元素 & 联合多个样式 2、使用拉姆达表达式 3、加上…

汇总区间,合并区间

题目一&#xff1a; 代码如下&#xff1a; vector<string> summaryRanges(vector<int>& nums) {vector<string> ret;if (nums.size() 0)return ret;int n nums.size();int i 0;while (i < n){int prev i;i;while (i < n && nums[i] n…

汽车MCU虚拟化--对中断虚拟化的思考(1)

目录 1.中断虚拟化的困惑 2.从R52入手 3.小结 1.中断虚拟化的困惑 在车控类控制器里&#xff0c;中断对于我们来说是非常宝贵的资源&#xff0c;可大幅提高系统实时性。 这些中断基本都属于实际物理硬中断(软中断另说)&#xff0c;例如对一个按键按下的中断响应&#xff0…

HR人才测评,企业人才综合素质测评?

HR企业人才综合素质测评是一种评估企业人才综合素质的方法。该测评方法通过对人才的综合能力、专业技能、沟通协调能力、团队合作能力、领导管理能力等方面进行评估&#xff0c;以期为企业提供更全面、更客观、更科学的人才选拔和管理的依据。 点击这里了解&#xff1a;『企业…

Usage - hackthebox

简介 靶场&#xff1a;hackmyvm 靶机&#xff1a;Usage(10.10.11.18) 难度&#xff1a;Easy 靶机链接:https://app.hackthebox.com/machines/Usage 攻击机1&#xff1a;ubuntu22.04 (10.10.16.21) 攻击机2&#xff1a;windows11(10.10.14.33) 扫描 nmap起手 nmap -sT …

云原生架构相关技术_1.容器技术

1.容器技术的背景与价值 容器作为标准化软件单元&#xff0c;它将应用及其所有依赖项打包&#xff0c;使应用不再受环境限制&#xff0c;在不同计算环境间快速、可靠地运行。容器部署模式与其他模式的比较如下图1所示。 图1 传统、虚拟化、容器部署模式比较 Docker容器基于操作…

四汇聚荣科技是靠谱的吗?

在当今这个科技飞速发展的时代&#xff0c;新兴科技公司如同雨后春笋般涌现。其中&#xff0c;四汇聚荣科技引起了人们的关注。许多人好奇&#xff0c;这家公司是否靠谱?它能否在激烈的市场竞争中站稳脚跟?接下来&#xff0c;让我们从四个不同的方面来深入探讨这个问题。 一、…

远程工作/线上兼职网站整理(数字游民友好)

文章目录 国外线上兼职网站fiverrupwork 国内线上兼职网站甜薪工场猪八戒网云队友 国外线上兼职网站 fiverr https://www.fiverr.com/start_selling?sourcetop_nav upwork https://www.upwork.com/ 国内线上兼职网站 甜薪工场 https://www.txgc.com/ 猪八戒网 云队友 …

首创十八道工艺,口味王引领槟榔产业高质量发展

说到槟榔&#xff0c;相信大伙都不会陌生&#xff0c;槟榔的历史可以追溯到汉代&#xff0c;不少文献有过记载&#xff0c;如汉代的沈约著的《咏竹槟榔盘》中提到“荐羞虽百品&#xff0c;所贵浮天实”&#xff1b;唐朝“诗仙”李白更是写道“何时黄金盘&#xff0c;一斛荐槟榔…

信号与槽函数的魔法:QT 5编程中的核心机制

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、信号与槽函数的基本概念 二、信号与槽函数的实现原理 三、信号与槽函数的代码实例 四…

使用Redis缓存实现短信登录逻辑,手机验证码缓存,用户信息缓存

引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency> 加配置 spring:redis:host: 127.0.0.1 #redis地址port: 6379 #端口password: 123456 #密码…

封装了一个iOS对号成功动画

基本思路其实很简单&#xff0c;就是通过贝塞尔曲线画出路径&#xff0c;然后 使用CAShapeLayer 渲染路径&#xff0c;然后通过strokeEnd 动画实现 路径的效果&#xff0c;这里注意&#xff0c;这个过程中过遇到过一个问题&#xff0c;就是 对号动画完成之后&#xff0c;整个对…

微服务 feign-gateway

早期微服务跨集群调用 使用的是Eureka 和RestTemplate&#xff0c;这种写法虽然可以解决服务之间的调用问题 ,但是随着服务的增多&#xff0c;实例变动&#xff0c;早期的写法相当于把请求方式&#xff0c;请求地址&#xff0c;参数写死了&#xff0c;耦合度太高&#xff0c;参…

C#知识|通用数据访问类SQLHelper的编写

哈喽,你好啊,我是雷工! 前面学习了C#操作SQLServer数据库数据的增删改查, 《C#知识|通过ADO.NET实现应用程序对数据库的增、删、改操作。》 其中实现的过程中有很多代码是重复的,此时作为高阶程序员为了使代码更优雅,避免重复, 从而要考虑代码的复用技术,针对此案例中代…

【稳定检索】2024年心理学与现代化教育、媒体国际会议(PMEM 2024)

2024年心理学与现代化教育、媒体国际会议 2024 International Conference on Psychology and Modern Education and Media 【1】会议简介 2024年心理学与现代化教育、媒体国际会议即将召开&#xff0c;这是一场汇聚全球心理学、教育及媒体领域精英的学术盛宴。 本次会议将深入探…

23 vue3面试重难点复习:响应式原理、特点、8大生命钩子、data数据定义、组件、全家桶

vue作为用的最为广泛的当前热门框架&#xff0c;总结如下重难点核心知识&#xff1a; 1.vue特点是什么&#xff1f; 1.1优点 渐进式 vue本身只提供数据响应式&#xff0c;需要全局缓存用 vuex&#xff0c;需要路由用 vue-router 组件化 封装组件&#xff0c;利于复用 响应式数…

美颜插件技术详解:第三方美颜SDK的选择与集成教学

为了满足用户对美颜的需求&#xff0c;开发者们可以利用第三方美颜SDK来快速、高效地集成美颜功能到他们的应用中。今天&#xff0c;小编将详细解析美颜插件技术&#xff0c;介绍如何选择适合的第三方美颜SDK&#xff0c;并提供集成教学指南。 一、美颜插件技术概述 通过美颜…