【Java】 大话数据结构(6) 栈的顺序与链式存储
本文根据《大话数据结构》一书,实现了Java版的栈的顺序存储结构、两栈共享空间、栈的链式存储机构。
栈:限定仅在表尾进行插入和删除操作的线性表。
栈的插入(进栈)和删除(出栈)操作如下图所示。
1.栈的顺序存储结构
用数组存放数据,top变量来指示栈顶元素在数组中的位置(栈顶指针)。一个长度为5的栈的示意图如下:
实现程序:
/**
* 栈的顺序储存结构
*
* 问题:构造器中,泛型数组创建是否有更好的方法?
* @author Yongh
*
*/
public class SqStack<E> {
private E[] data;
private int top; //栈顶指针,top=-1时为空栈
private int maxSize;
private static final int DEFAULT_SIZE= 10; public SqStack() {
this(DEFAULT_SIZE);
}
public SqStack(int maxSize) {
//无法创建泛型数组 data=new E[maxSize];
data=(E[]) new Object[maxSize];
top=-1;
this.maxSize=maxSize;
} public void push(E e) {
if(top==maxSize-1)
throw new RuntimeException("栈已满,无法进栈!");
top++;
data[top]=e;
} public E pop() {
if(top==-1)
throw new RuntimeException("空栈,无法出栈!");
E e=data[top];
top--;
return e;
} public void printStack() {
if(top==-1) {
System.out.println("空栈");
}else {
for(int i=0;i<=top;i++) {
System.out.println(data[i]);
}
}
}
}
测试代码:
public class StackTest {
public static void main(String[] args) {
SqStack<Student> sqStack=new SqStack<Student>();
Student[] students= {new Student("小A",11),new Student("小B",12),new Student("小C",13),
new Student("小D",14),new Student("小E",151)};
for(int i=0;i<5;i++) {
sqStack.push(students[i]);
}
sqStack.printStack();
for(int i=0;i<5;i++) {
sqStack.pop();
}
sqStack.printStack();
}
} class Student{
public Student(String name, int age) {
this.name=name;
this.age=age;
}
String name;
int age;
public String toString() {
return name;
}
}
小A
小B
小C
小D
小E
空栈
StackTest
2.两栈共享空间
通过一个数组存放两个栈,能较好地利用空间。用top1和top2变量表示栈1和栈2的栈顶指针,两个栈的栈底分别位于数组的头部和尾部。
实现程序(在SqStack程序的基础上稍加改造即可):
/**
* 栈的顺序储存结构(两栈共享空间)
*
* 注意点:栈满条件为top1+1==top2
*
* @author Yongh
*
*/
public class SqDoubleStack<E> {
private E[] data;
private int top1; //栈1栈顶指针,top=-1时为空栈
private int top2; //栈2栈顶指针,top=maxSize-1时为空栈
private int maxSize;
private static final int DEFAULT_SIZE= 10; public SqDoubleStack() {
this(DEFAULT_SIZE);
}
public SqDoubleStack(int maxSize) {
//无法创建泛型数组 data=new E[maxSize];
data=(E[]) new Object[maxSize];
top1=-1;
top2=maxSize-1;
this.maxSize=maxSize;
} /*
* 进栈操作,stackNumber代表要进的栈号
*/
public void push(int stackNumber,E e) {
if(top1+1==top2)
throw new RuntimeException("栈已满,无法进栈!");
if(stackNumber==1) {
data[++top1]=e;
}else if(stackNumber==2) {
data[--top2]=e;
}else {
throw new RuntimeException("栈号错误!");
} } /*
* 出栈操作
*/
public E pop(int stackNumber) {
E e;
if(stackNumber==1){
if(top1==-1)
throw new RuntimeException("空栈1,无法出栈!");
e=data[top1--];
}else if(stackNumber==2) {
if(top2==maxSize-1)
throw new RuntimeException("空栈2,无法出栈!");
e=data[top2++];
}else {
throw new RuntimeException("栈号错误!");
}
return e;
}
}
3.栈的链式存储结构
通过单向链表实现的栈,栈顶放在单链表的头部(注意进栈操作并不是往链表的后面插入,而是从头部插入)。
链栈的示意图如下。
插入与删除操作示意图:
实现程序:
/**
*
* 栈的链式存储结构
*
* @author Yongh
*/
public class LinkStack<E> {
private StackNode<E> top;
private int count; private class StackNode<E>{
E data;
StackNode<E> next;
public StackNode(E data,StackNode<E> next) {
this.data=data;
this.next=next;
}
} public LinkStack() {
top=new StackNode<E>(null, null);
count=0;
} public void push(E e) {
StackNode<E> node=new StackNode<E>(e, top);
top=node;
count++;
} public E pop() {
if(count==0)
throw new RuntimeException("空栈,无法出栈!");
StackNode<E> node;
node=top;
top=top.next;
count--;
E e=node.data;
node=null;
return e;
} public void printStack() {
if(count==0) {
System.out.println("空栈");
}else {
StackNode<E> node=top;
for(int i=0;i<count;i++) {
System.out.println(node.data);
node=node.next;
}
}
} /*
* 测试代码
*/
public static void main(String[] args) {
LinkStack<Student> linkStack=new LinkStack<Student>();
Student[] students= {new Student("小A",11),new Student("小B",12),new Student("小C",13),
new Student("小D",14),new Student("小E",151)};
for(int i=0;i<5;i++) {
linkStack.push(students[i]);
}
linkStack.printStack();
System.out.println("----");
for(int i=0;i<5;i++) {
System.out.println(linkStack.pop());
}
linkStack.printStack();
}
}
小E
小D
小C
小B
小A
----
小E
小D
小C
小B
小A
空栈
LinkStack
4.栈的应用
(1)实现递归
一些问题(如斐波那契数列的求解),可通过递归函数获得,而递归函数是由栈来实现的。
典型的斐波那契数列
(2)四则运算表达式求值
利用后缀表达式(逆波兰表示法)结合栈可以实现四则运算表达式的求解。而且通过栈,就可以把我们平时用的中缀表达式转化为后缀表达式。
【Java】 大话数据结构(6) 栈的顺序与链式存储的更多相关文章
- 栈的顺序存储和链式存储c语言实现
一. 栈 栈的定义:栈是只允许在一端进行插入或删除操作的线性表. 1.栈的顺序存储 栈顶指针:S.top,初始设为-1 栈顶元素:S.data[S.top] 进栈操作:栈不满时,栈顶指针先加1,再到栈 ...
- c数据结构 -- 线性表之 复杂的链式存储结构
复杂的链式存储结构 循环链表 定义:是一种头尾相接的链表(即表中最后一个结点的指针域指向头结点,整个链表形成一个环) 优点:从表中任一节点出发均可找到表中其他结点 注意:涉及遍历操作时,终止条件是判断 ...
- [置顶] ※数据结构※→☆线性表结构(queue)☆============优先队列 链式存储结构(queue priority list)(十二)
优先队列(priority queue) 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除.在优先队列中,元素被赋予优先级.当访问元素时,具有最高优先级的元素最先删除.优先队列具有 ...
- java资料——顺序存储结构和链式存储结构(转)
顺序存储结构 主要优点 节省存储空间,随机存取表中元素 缺 点 插入和删除操作需要移动元素 在计算机中用一组地址连续的存储单元依次存储线性表的各个数据元素,称作线性表的顺序存储结构. 顺序存储结 ...
- 数据结构----线性表顺序和链式结构的使用(c)
PS:在学习数据结构之前,我相信很多博友也都学习过一些语言,比如说java,c语言,c++,web等,我们之前用的一些方法大都是封装好的,就java而言,里面使用了大量的封装好的方法,一些算法也大都写 ...
- C语言- 基础数据结构和算法 - 栈的链式存储
听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...
- javascript实现数据结构:线性表--线性链表(链式存储结构)
上一节中, 线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单,直观的公式来表示.然后,另一方面来看,这个特点也造成这种存储 ...
- Java实现链式存储的二叉树
二叉树的定义: 二叉树(BinaryTree)是n(n≥0)个结点的有限集,它或者是空集(n=0),或者由一个根结点及两棵互不相交的.分别称作这个根的左子树和右子树的二叉树组成. 二叉树的遍历方式主要 ...
- C++编程练习(4)----“实现简单的栈的链式存储结构“
如果栈的使用过程中元素数目变化不可预测,有时很小,有时很大,则最好使用链栈:反之,如果它的变化在可控范围内,使用顺序栈会好一些. 简单的栈的链式存储结构代码如下: /*LinkStack.h*/ #i ...
随机推荐
- 【bzoj4765】 普通计算姬
题意 给出一棵有根树,$n$个点每个都有一个点权.$m$组操作每次可以修改一个点权或者询问编号在区间$[l,r]$的点的子树权值和的和. Solution 我们对节点编号分块,每一块统计该块中的节点的 ...
- 51nod 1577 异或凑数
思路真的是挺巧妙的. 让我惊叹,原来线性基还能这么做?!?! 好吧,这种取若干个数异或凑数的题目怎么能少的了线性基呢? 但是,问题集中在于怎么快速提取一个区间的线性基 暴力n^2 线段树维护线性基?分 ...
- (转)java中使用memcache
背景:公司项目中使用java和memcache相结合来搭建缓存,所以要了解下缓存的基础知识! 1 了解memcache 1.1 基础知识 什么是Memcache? Memcache集群环境下缓存解决方 ...
- c读入实型
读入: 如果读入的数为整型,然后转为实型,则%lf 否则%f也可以 读出: %f,这样在codeblocks才能看到正确的结果
- 「Django」浏览+1的操作
适应于网页.文章等浏览次数统计 1.Models设置:添加viewed方法 class NewsTitle(models.Model): title = models.CharField(max_le ...
- 在“安装”阶段发生异常。 System.Security.SecurityException: 未找到源,但未能
写Windows服务的时候,运行了一下,就是没反应,命令框一闪而过,查了一下异常,大致是题目的那样.原因是因为权限不足.但是在网上搜的方法都不顶用. 解决方法如下: (1)以管理员身份运行CMD: ( ...
- linq中let关键字学习
linq中let关键字就是对子查询的一个别名,let子句用于在查询中添加一个新的局部变量,使其在后面的查询中可见. linq中let关键字实例 1.传统下的子查询与LET关键字的区别 C# 代 ...
- SQLSTATE[42000]
SQLSTATE[42000]: Syntax error or access violation: 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT() ...
- 一个查看Access数据库密码的工具
一个可以查看Access数据库密码的工具AccessCracker.需要.net2.0环境支持. 网盘地址:https://pan.baidu.com/s/1btbsFcsKO0Enj-rjkTlz6 ...
- 什么是Jupyter Notebook?
Jupyter Notebook, 以前又称为IPython notebook,是一个交互式笔记本, 支持运行40+种编程语言. 可以用来编写漂亮的交互式文档. Linux下, Jupyter Not ...