java 队列 栈_详细分析栈和队列的数据结构的实现过程(Java 实现)

栈和队列的数据结构的实现过程(Java 实现)

栈的数据结构的实现

栈的基础知识回顾

栈是一种线性结构。

相比数组,栈对应的操作是数组的子集。

也就是栈可基于数组实现,可以将栈看成一种特殊的数组。

栈只能从一端添加元素,也只能从一端取出元素,这一端称为栈顶。

栈是一种 后进先出 (LIFO: Last In First Out) 的数据结构。

栈的常见应用

撤销(Undo)操作

de41c1e182d70bad95083f308c6d0ca2.gif

程序调用的系统栈

584cc28f1454b908927eb06d3364fcaa.gif

ccdb0fae261cb54dad6ddcee4ce335ac.png

基于数组的栈的实现

对于栈这种数据结构,实现起来是十分简单的,这里实现以下几个操作:

入栈:void push(E element)

8c9d5417029e63af615b565e2fabea18.gif

出栈: E pop()

22330a25a7d00c43b3a8b32c43d86716.gif

查看栈顶元素: E peek()

81d23ec294579768199bcb030d56df18.gif

获取栈中元素个数: int getSize()

686d9aa16df5c14f232ac839b5aa2fb5.png

判断栈是否为空: boolean: isEmpty()

874c43382b0126d6189b167e8ac69e6b.png

对于代码的具体实现,可以让其支持多态性。所以可以设计一个接口 Stack 定义上面这 5 个栈支持的操作,再设计一个类 ArrayStack 来实现这个接口。

对于 ArrayStack 这个类,实质上是基于之前实现的动态数组类 Array 来实现的一个数组栈。因为对于栈而言,栈对应的操作是数组的子集。可以把栈当成一个数组来看待。

对于 Array 类的具体实现过程,可查看另一篇 文章 。

具体代码设计

在编写栈的具体代码之前,先往工程中导入之前实现的动态数组类 Array,该类代码可从之前的文章中查阅, 因为要基于该类来实现数组栈。

7f824285deff666db19a1f94caa2dcac.png

ArrayStack 类的实现:

因为在 Array 类中已经实现了很多操作数组的方法。所以对于 ArrayStack 类实现接口中的方法时,只需复用 Array 类中的方法即可。

基于 Array 类实现 ArrayStack 类也有一些好处:

和 Array 一样拥有了动态伸缩容量的功能,我们不需要关心栈的容量是否够用,因为容量会动态地进行扩大和缩小。

对于一些非法变量的判断直接复用了 Array 类中的代码,不需要重复编写。

同时,也可以为 ArrayStack 类添加一个接口中没有的方法 getCapacity 提供给用户获取栈的容量。这个方法是这个类中特有的。

在实现 peek 方法之前,可以在 Array 类中扩展两个新方法用于获取数组末尾和数组首部的元素,方便在 ArrayStack 类和后续队列的实现中直接复用。

/**

* 获取数组的最后一个元素

*

* @return 返回数组的最后一个元素

*/

public E getLast() {

return get(size - 1);

}

/**

* 获取数组的第一个元素

*

* @return 返回数组的第一个元素

*/

public E getFirst() {

return get(0);

}

Stack 接口类代码如下:

/**

* 定义栈的基本操作的接口

* 支持泛型

*

* @author 踏雪寻梅

* @date 2020/1/8 - 19:20

*/

public interface Stack {

/**

* 获取栈中元素个数

*

* @return 栈中如果有元素,返回栈中当前元素个数;栈中如果没有元素返回 0

*/

int getSize();

/**

* 判断栈是否为空

*

* @return 栈为空,返回 true;栈不为空,返回 false

*/

boolean isEmpty();

/**

* 入栈

* 将元素 element 压入栈顶

*

* @param element 入栈的元素

*/

void push(E element);

/**

* 出栈

* 将当前栈顶元素出栈并返回

*

* @return 返回当前出栈的栈顶元素

*/

E pop();

/**

* 查看当前栈顶元素

*

* @return 返回当前的栈顶元素

*/

E peek();

}

ArrayStack 类代码实现如下:

/**

* 基于之前实现的动态数组类 Array 实现的数组栈类 ArrayStack

* 同样支持泛型

*

* @author 踏雪寻梅

* @date 2020/1/8 - 19:26

*/

public class ArrayStack implements Stack {

/**

* 动态数组 array

* 基于 array 实现栈的操作

*/

private Array array;

/**

* 构造函数

* 创建一个容量为 capacity 的数组栈

*

* @param capacity 要创建的栈的容量,由用户指定

*/

public ArrayStack(int capacity) {

array = new Array<>(capacity);

}

/**

* 默认构造函数

* 创建一个默认容量的数组栈

*/

public ArrayStack() {

array = new Array<>();

}

@Override

public int getSize() {

// 复用 array 的 getSize() 方法即可

return array.getSize();

}

@Override

public boolean isEmpty() {

// 复用 array 的 isEmpty() 方法即可

return array.isEmpty();

}

/**

* 获取栈的容量

* ArrayStack 特有的方法

*

* @return 返回栈的容量

*/

public int getCapacity() {

// 复用 array 的 getCapacity() 方法即可

return array.getCapacity();

}

@Override

public void push(E element) {

// 将数组的末尾作为栈顶,复用 array 的 addLast() 方法实现

array.addLast(element);

}

@Override

public E pop() {

// 将数组的末尾作为栈顶,复用 array 的 removeLast() 方法将栈顶元素出栈并返回

return array.removeLast();

}

@Override

public E peek() {

// 将数组的末尾作为栈顶,复用 array 的 getLast() 方法获取栈顶元素

return array.getLast();

}

/**

* 重写 toString 方法返回数组栈的信息

*

* @return 返回数组栈的当前信息

*/

@Override

public String toString() {

StringBuilder result = new StringBuilder();

result.append("ArrayStack: ");

result.append("size: ").append(array.getSize()).append(" ");

result.append("capacity: ").append(array.getCapacity()).append(" ");

result.append("bottom -> [ ");

for (int i = 0; i < array.getSize(); i++) {

result.append(array.get(i));

// 如果不是最后一个元素

if (i != array.getSize() - 1) {

result.append(", ");

}

<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值