从“0“开始学数据结构和算法01——栈stack

目录

关于数据结构的简单介绍

线性结构

非线性结构

栈的运行方式

栈的实现方式

代码实现

栈的应用场景

Java子程序的调用

处理递归调用

中缀表达式转换成后缀表达式(逆波兰表达式)

二叉树的遍历

图形深度优先搜索法


关于数据结构的简单介绍

线性结构

线性结构属于一种有序的数据元素集合,存在一一对应的线性关系,并且线性结构中只能存储相同类型的数据。类似于小朋友手拉手,对于中间的元素来说前一元素叫做前趋,后一元素叫做后继。常用的线性结构有:线性表,栈,队列,双队列,数组,串。 

非线性结构

没有线性结构那样的性质。一个元素可以对应多个节点,与之对应的前者都叫做前趋,后续的节点都叫后继。常见的非线性结构有:二维数组,多维数组,广义表,树(二叉树等)。

栈是一种限制了插入和删除只能在末端进行的线性表。末端操作位置称为栈顶(top),不允许操作的位置成为栈底(bottom)。插入数据的操作称之为压栈(push)取出(弹出)数据的操作叫做弹栈(出栈,pop)。由于栈的原理是表,也就意味着任何实现表的方法都可以在栈上实现。栈的时间复杂度为O(n),其他操作均为O(1)

栈的主要实现方式为链表或者数组。 使用数组实现的栈称为静态栈,使用单链表实现的栈称为动态栈。

Java中由于开发人员的疏忽,使stack继承了vector成为父子关系而不是组合关系,导致stack变成了一种糟糕的设计(相关内容可以自行查阅),从此在Java中开发人员并不推荐使用stack作为栈来存储数据,但后续版本中开发人员在Java文档中推荐使用Deque(双端队列)来实现栈,而Deque可以在两头进行数据操作,和原始的栈还是相差甚远,可以对Deque接口进行实现,创建自己的栈,使一端无法被操作从而实现栈的功能。

栈的运行方式

栈的实现方式

使用数组实现栈

  1. 首先定义一个数组用于存储数据,数组长度固定
  2. 定义top表示栈顶,初始化数据为-1
  3. 入栈时,数据存入,top++
  4. 出栈时,数据删除,top--

代码实现

public class StackModel {
	
	/** 定义栈内存 */
	private int stack[];

	/** 栈顶 初始化为 -1*/
	private int top =-1;
	
	/**
	 * 初始化数组
	 * @param i
	 */
	public StackModel(int i) {
		stack = new int[i];
	}
	
	/**
	 * 数据入栈 
	 * @param i
	 */
	public void push(int i) {
		top++;
		stack[top]=i;
	}
	
	public void pop() {
		stack[top]=0;
		top--;
	}
	
	public void query() {
		if(top==-1) {
			return;
		}
		for(int i=0;i<=top;i++) {
			System.out.println(stack[i]);
		}
	}
	
}

栈的应用场景

Java子程序的调用

为了有效的防止栈溢出,在循环遍历的时候,我们必须在循环条件中加入停止条件,不能使程序进入死循环,当然递归也是如此 

处理递归调用

和子程序调用一样,只不过在入栈时,不仅记录了方法,还记录了一些参数

中缀表达式转换成后缀表达式(逆波兰表达式)

我们正常人类习惯的计算方式1+2*3(这样的表达式为中缀表达式)而计算机无法识别这样的表达式,因为计算机只能按照顺序依次进行计算,但要想在计算过程中体现出优先级,就必须把这样的中缀表达式变成另外一种表达式,即后缀表达式。

中缀表达式后缀表达式
1+212+
1+2*3123*+
(1+2)*3123+*

以表格中第二列为例子,在中缀表达式转后缀表达式时,需要数字栈和符号栈。由于栈插入数据的特点是先入后出,所以当1+2*3时,1最先入栈,会被放在最下面,其次2再入栈,再到3。而符号栈中,*的优先级大于+所以*号先入栈,此时将2和3弹栈相乘再入栈,再将+号入栈时,取出1和6(由2*3得来)进行相加

二叉树的遍历

以上图为例,绿色箭头为入栈,红色箭头为出栈。当我们需要在二叉树中遍历时,从根节点7开始出发, 来到左节点,将左节点的5记录在栈中,再前往右节点,将右节点的6记录在栈中。最终输出需要查找的元素6。其余元素的获取方法都是如此。

图形深度优先搜索法

和二叉树的遍历一致,在遍历时会记录在栈中。


这个系列的博客都是我在学习数据结构和算法中,我个人的一些看法和见解,欢迎各位大佬指正

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值