数据结构===栈

文章目录

  • 栈的定义
  • 实现一个栈
    • 用数组实现栈
    • 用链表实现栈
    • 支持动态扩容的栈
  • 栈的应用
  • 小结

栈的定义

栈是一种先进后出的数据结构。它的操作受限。

栈,是一种先进后出,或者后进先出的数据结构。跟数组和链表相比,有一定的限制性。毕竟,它也有自己的适用场景,比如:函数调用,表达式求值等等。栈有2个操作,入栈,出栈。时间复杂度都是O(1)。

实现一个栈

实现一个栈:怎么实现呢,有2种方式,用数组实现或者用链表实现。用数组实现的叫做顺序栈,用链表实现的叫做链式栈。

用数组实现栈

先用数组实现,不考虑扩容的情况,代码如下:

class Stack:def __init__(self):self.stack = []# 入栈操作def push(self, item):self.stack.append(item)# 出栈操作def pop(self):if not self.is_empty():return self.stack.pop()else:return None# 查看栈顶元素def peek(self):if not self.is_empty():return self.stack[-1]else:return None# 判断栈是否为空def is_empty(self):return len(self.stack) == 0# 获取栈的大小def size(self):return len(self.stack)

这是python的实现方式。可以再看下java的实现方式,如下图:

public class Stack {private int[] elements;private int top;private int capacity;// 初始化栈,设置初始容量public Stack(int capacity) {this.capacity = capacity;elements = new int[capacity];top = -1; // 初始时栈顶为-1,表示栈为空}// 入栈操作public void push(int item) {if (!isFull()) {top++;elements[top] = item;} else {System.out.println("栈已满,无法添加元素");}}// 出栈操作public int pop() {if (!isEmpty()) {return elements[top--];} else {System.out.println("栈为空,无法删除元素");return -1; // 或者可以抛出一个异常}}// 查看栈顶元素public int peek() {if (!isEmpty()) {return elements[top];} else {System.out.println("栈为空,没有元素可查看");return -1; // 或者可以抛出一个异常}}// 检查栈是否为空public boolean isEmpty() {return top == -1;}// 检查栈是否已满private boolean isFull() {return top == capacity - 1;}// 获取栈的大小public int size() {return top + 1;}// 展示栈的内容(可选)public void displayStack() {if (isEmpty()) {System.out.println("栈为空");} else {for (int i = top; i >= 0; i--) {System.out.print(elements[i] + " ");}System.out.println();}}// 主函数,用于测试栈的实现public static void main(String[] args) {Stack stack = new Stack(5); // 创建一个容量为5的栈stack.push(1);stack.push(2);stack.push(3);stack.displayStack(); // 显示栈的内容System.out.println("栈顶元素: " + stack.peek());stack.pop();stack.pop();stack.displayStack(); // 再次显示栈的内容System.out.println("栈的大小: " + stack.size());System.out.println("栈是否为空: " + stack.isEmpty());}
}

用链表实现栈

用数组实现完了,再用链表实现,如下图:

class Node:def __init__(self, data=None):self.data = dataself.next = Noneclass Stack:def __init__(self):self.top = None# 入栈操作def push(self, data):if self.top is None:self.top = Node(data)else:new_node = Node(data)new_node.next = self.topself.top = new_node# 出栈操作def pop(self):if self.top is None:return Noneelse:popped = self.top.dataself.top = self.top.nextreturn popped# 查看栈顶元素def peek(self):return self.top.data if self.top else None# 判断栈是否为空def is_empty(self):return self.top is None# 测试代码
s = Stack()
s.push(1)
s.push(2)
s.push(3)
print(s.pop())  # 输出:3
print(s.peek())  # 输出:2
print(s.is_empty())  # 输出:False

java的实现方式,如下图:

public class Node<T> {private T data;private Node<T> next;public Node(T data) {this.data = data;this.next = null;}public T getData() {return data;}public void setData(T data) {this.data = data;}public Node<T> getNext() {return next;}public void setNext(Node<T> next) {this.next = next;}
}public class LinkedListStack<T> {private Node<T> top;public LinkedListStack() {this.top = null;}// 入栈操作public void push(T data) {Node<T> newNode = new Node<>(data);newNode.setNext(top);top = newNode;}// 出栈操作public T pop() {if (isEmpty()) {throw new IllegalStateException("Stack is empty");}T data = top.getData();top = top.getNext();return data;}// 查看栈顶元素public T peek() {if (isEmpty()) {throw new IllegalStateException("Stack is empty");}return top.getData();}// 判断栈是否为空public boolean isEmpty() {return top == null;}// 获取栈的大小public int size() {int size = 0;Node<T> current = top;while (current != null) {size++;current = current.getNext();}return size;}// 测试代码public static void main(String[] args) {LinkedListStack<Integer> stack = new LinkedListStack<>();stack.push(200);stack.push(300);stack.push(600);System.out.println(stack.pop());  System.out.println(stack.peek());  System.out.println(stack.isEmpty()); System.out.println(stack.size());  }
}

好了,实现方式就是这样的。再来看看动态扩容的栈是怎么实现的。

支持动态扩容的栈

这个跟普通的栈有一个不同的地方,在入栈的时候栈满了会进行扩容,然后复制之前的数据,再进行入栈操作。用java实现,如下图:

public class DynamicArrayStack<T> {private static final int DEFAULT_CAPACITY = 10;private static final int RESIZE_FACTOR = 2;private Object[] elements;private int top;public DynamicArrayStack() {elements = new Object[DEFAULT_CAPACITY];top = -1;}// 入栈操作public void push(T item) {ensureCapacity();elements[++top] = item;}// 出栈操作public T pop() {if (isEmpty()) {throw new EmptyStackException();}return (T) elements[top--];}// 查看栈顶元素public T peek() {if (isEmpty()) {throw new EmptyStackException();}return (T) elements[top];}// 判断栈是否为空public boolean isEmpty() {return top == -1;}// 获取栈的大小public int size() {return top + 1;}// 确保数组有足够的容量private void ensureCapacity() {if (top == elements.length - 1) {resize();}}// 调整数组大小private void resize() {int newSize = elements.length * RESIZE_FACTOR;elements = Arrays.copyOf(elements, newSize);}// 测试代码public static void main(String[] args) {DynamicArrayStack<Integer> stack = new DynamicArrayStack<>();stack.push(1);stack.push(2);stack.push(3);System.out.println(stack.pop());  // 输出:3System.out.println(stack.peek());  // 输出:2System.out.println(stack.size());  // 输出:2System.out.println(stack.isEmpty());  // 输出:false}
}

栈的应用

栈应用非常多,比如,在浏览器里有个向前,向后的箭头,就可以用2个栈来存储;函数的调用,也是可以用栈的。例子就不多举了。

小结

这篇文章讲述了栈的数据结构。

主要是讲解了栈的数据结构,以及实现,目的是了解底层的数据结构及应用,还有动态扩容的栈,栈的时间复杂度,空间复杂度都是O(1)。基本上就这么多。至于实现,用什么语言不重要,原理懂了,写一个,应该都不是什么难事。

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

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

相关文章

有哪些开源协议?

目前存在多种开源协议&#xff0c;它们各自有不同的特点和适用场景&#xff0c;旨在保护开发者权利的同时促进软件的共享和协作。以下是几种常见的开源协议&#xff1a; MIT License&#xff08;麻省理工学院许可证&#xff09;&#xff1a; 非常宽松的许可&#xff0c;基本上允…

文件导入导出【开发实践】

文章目录 一、背景和基础知识1.1 文件导入1.2 文件导出1.3 技术背景1.4 Excel的基本知识1.5 文件导入/导出流程 二、使用EasyExcel完成读写Excel操作2.1 创建实体类并完成映射2.1.1 用在字段上的注解2.1.1.1 ExcelProperty&#xff08;最重要&#xff09;2.1.1.2 ColumnWidth2.…

低代码工业组态数字孪生平台

2024 两会热词「新质生产力」凭借其主要特征——高科技、高效能及高质量&#xff0c;引发各界关注。在探索构建新质生产力的重要议题中&#xff0c;数据要素被视为土地、劳动力、资本和技术之后的第五大生产要素。数据要素赋能新质生产力发展主要体现为&#xff1a;生产力由生产…

springcloud中Gateway基本配置包含原理与示例

Gateway基本配置包含原理与示例 一、Gateway简介 Gateway是Spring Cloud生态系统中的一个基于Spring Framework 5&#xff0c;Project Reactor和Spring Boot 2的API网关服务。它旨在为微服务架构提供一种简单而有效的方式来路由请求、过滤请求以及对请求进行转换。Gateway可以…

【linuxC语言】fcntl和ioctl函数

文章目录 前言一、功能介绍二、具体使用2.1 fcntl函数2.2 ioctl函数 三、拓展&#xff1a;填写arg总结 前言 在Linux系统编程中&#xff0c;经常会涉及到对文件描述符、套接字以及设备的控制操作。fcntl和ioctl函数就是用来进行这些控制操作的两个重要的系统调用。它们提供了对…

Visual Studio中怎样更改Nuget程序包源

场景 Visual Studio 2019 在使用NuGet添加依赖包时&#xff0c;在预览中搜索不到程序包。 排查下NuGet的程序包源为本地。 将程序包源修改下。 实现 在解决方案上右击选择管理解决方案中的NuGet程序包(在 Visual Studio 中打开“工具”>“选项”>“NuGet 包管理器”…

请求路径引发的http308错误

记录一个请求路径输错引发的问题。 正确路径&#xff1a; /user/bind-email 请求路径我们如果输错故意多打一个s /user/bind-emails 正常预检请求会报错404未找到&#xff0c;我们下意识的就去排查路径是不是写错了 但是如果多打一个/ /user//bind-email 此时预检请求会报308永…

Linux 指令lsblk 作用,以及查看cpu使用情况和磁盘IO iostat指令详解

lsblk 指令 在Linux系统中&#xff0c;lsblk&#xff08;列表块设备&#xff09;命令是一个非常实用的工具&#xff0c;用于显示所有可用的块设备信息&#xff0c;如硬盘、USB驱动器、SD卡以及它们的分区。这个命令以易于理解的树状结构展示这些信息&#xff0c;清晰地表明了设…

Java中优雅实现泛型类型的强制转换

在Java中经常遇到将对象强制转换成泛型类的情况&#xff1a; Map<String, Object> data Map.of("name", "XiaoMing","age", 17,"scores", List.of(80, 90, 70) );List<Integer> scores (List<Integer>) data.get…

ASP.NET数据存储与交换系统设计

摘 要 该系统以Microsoft Visual Studio 2003作为开发工具&#xff0c;选用SQL Server 2000数据库来实现数据存储&#xff0c;并设计开发了一种基于B/S模式的数据存储与交换系统。该系统完成了用户注册管理、后台管理和用户空间管理功能&#xff1b;为每个用户提供了个人的存…

数据结构中的栈(C语言版)

一.栈的概念 栈是一种常见的数据结构&#xff0c;它遵循后进先出的原则。栈可以看作是一种容器&#xff0c;其中的元素按照一种特定的顺序进行插入和删除操作。 压栈&#xff1a;栈的插入操作叫做进栈/压栈/入栈&#xff0c;入数据在栈顶。 出栈&#xff1a;栈的删除操作叫做…

区块链技术:DAPP开发

随着科技的飞速发展&#xff0c;区块链技术逐渐渗透到各个领域&#xff0c;其中DAPP&#xff08;去中心化应用&#xff09;的发展尤为引人注目。作为一种新型的应用程序&#xff0c;DAPP正在重塑未来商业生态&#xff0c;其潜力无可估量。 一、DAPP的定义和特点 DAPP是指基于…

等保保护测评试题中

二、多选题 1、防火墙提供的接入模式中包括&#xff08;ABCD&#xff09; A.网关模式 B.透明模式 C.混合模式 D.旁路接入模式 2、不同设VLAN之间要进行通信&#xff0c;可以通过 .&#xff08;AB&#xff09; A.交换机 B.路由器 C.网闸 D.入侵检测 E.入侵防御系统…

美国国防部数据网格参考架构概述(上)

文章目录 前言一、概述二、DRMA基本概念三、DRMA的能力视图与运行视图前言 美国国防部正在努力成为“一个以数据为中心的组织,以速度和规模优势使用数据,从而获得作战优势并提高效率。”企业数据网格服务(又称数据集成层)是美国国防部首席数字与人工智能办公室(CDAO)为支…

error loading module ‘cjson‘ from file ‘.\cjson.dll‘:找不到指定的程序。

编译lua-cjson 项目&#xff1a;https://github.com/openresty/lua-cjson 克隆下来后使用vs2022创建工程 添加三个文件即可 fpconv.c lua_cjson.c strbuf.c 配置项目工程 lua头文件目录 链接器lua库文件目录 配置lua头文件 luaxxx/src 配置lua库文件 luaxxx.lib 编译d…

基于ssm+vue+Mysql的房屋租赁系统求租合同

开发语言&#xff1a;Java框架&#xff1a;ssmJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;Maven3.…

交通运输智慧监管平台---强化物流安全与效率的新举措

一、建设背景 随着社会对于交通安全和环境保护的要求不断提高&#xff0c;对卡车运输的监管和合规性要求也逐渐加强。为了满足快速发展的物流需求&#xff0c;提高供应链协同和可追溯性、解决安全问题、提高运输效率和降低成本&#xff0c;我们利用现代技术和信息化手段着力建设…

ctfshow——SQL注入

文章目录 SQL注入基本流程普通SQL注入布尔盲注时间盲注报错注入——extractvalue()报错注入——updataxml()Sqlmap的用法 web 171——正常联合查询web 172——查看源代码、联合查询web 173——查看源代码、联合查询web 174——布尔盲注web 176web 177——过滤空格web 178——过…

nginx下载安装配置(含ssl)

下载安装环节 wget https://nginx.org/download/nginx-1.24.0.tar.gz tar -zxvf xxx.tar.gz yum -y install pcre-devel openssl openssl-devel ./configure --prefix/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-stream make & make i…

HTTP协议 --中

http状态码 当浏览者访问一个网页时&#xff0c;浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前&#xff0c;此网页所在的服务器会返回一个包含HTTP 状态码的信息头&#xff08; server header &#xff09;用以响应浏览器的请求。 HTTP 状态码的英文为…