本文根据《大话数据结构》一书,实现了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) 栈的顺序与链式存储的更多相关文章

  1. 栈的顺序存储和链式存储c语言实现

    一. 栈 栈的定义:栈是只允许在一端进行插入或删除操作的线性表. 1.栈的顺序存储 栈顶指针:S.top,初始设为-1 栈顶元素:S.data[S.top] 进栈操作:栈不满时,栈顶指针先加1,再到栈 ...

  2. c数据结构 -- 线性表之 复杂的链式存储结构

    复杂的链式存储结构 循环链表 定义:是一种头尾相接的链表(即表中最后一个结点的指针域指向头结点,整个链表形成一个环) 优点:从表中任一节点出发均可找到表中其他结点 注意:涉及遍历操作时,终止条件是判断 ...

  3. [置顶] ※数据结构※→☆线性表结构(queue)☆============优先队列 链式存储结构(queue priority list)(十二)

    优先队列(priority queue) 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除.在优先队列中,元素被赋予优先级.当访问元素时,具有最高优先级的元素最先删除.优先队列具有 ...

  4. java资料——顺序存储结构和链式存储结构(转)

    顺序存储结构 主要优点 节省存储空间,随机存取表中元素 缺    点 插入和删除操作需要移动元素 在计算机中用一组地址连续的存储单元依次存储线性表的各个数据元素,称作线性表的顺序存储结构. 顺序存储结 ...

  5. 数据结构----线性表顺序和链式结构的使用(c)

    PS:在学习数据结构之前,我相信很多博友也都学习过一些语言,比如说java,c语言,c++,web等,我们之前用的一些方法大都是封装好的,就java而言,里面使用了大量的封装好的方法,一些算法也大都写 ...

  6. C语言- 基础数据结构和算法 - 栈的链式存储

    听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...

  7. javascript实现数据结构:线性表--线性链表(链式存储结构)

    上一节中, 线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单,直观的公式来表示.然后,另一方面来看,这个特点也造成这种存储 ...

  8. Java实现链式存储的二叉树

    二叉树的定义: 二叉树(BinaryTree)是n(n≥0)个结点的有限集,它或者是空集(n=0),或者由一个根结点及两棵互不相交的.分别称作这个根的左子树和右子树的二叉树组成. 二叉树的遍历方式主要 ...

  9. C++编程练习(4)----“实现简单的栈的链式存储结构“

    如果栈的使用过程中元素数目变化不可预测,有时很小,有时很大,则最好使用链栈:反之,如果它的变化在可控范围内,使用顺序栈会好一些. 简单的栈的链式存储结构代码如下: /*LinkStack.h*/ #i ...

随机推荐

  1. 做前端好还是Java好?

    做前端好还是Java好?看这三方面 转载 2017年11月14日 00:00:00 1047这几年来伴随着互联网的迅速发展,新兴互联网产业的兴起,传统行业也逐渐开始互联网化,使得互联网职业在这样的背景 ...

  2. #include<iostream>与#include<iostream.h>以及#inclue<string> 和 #include<string.h>的区别

    转载于:http://www.cnblogs.com/charley_yang/archive/2010/12/08/1900715.html 1.从功能性的角度来讲,<iostream> ...

  3. Gulp安装笔记(转)已经测试过

    前言 总的来说,玩gulp的流程是这样的: 安装nodejs -> 全局安装gulp -> 项目安装gulp以及gulp插件 -> 配置gulpfile.js -> 运行任务 ...

  4. phpstorm 配置 webpack @ 别名跳转

    webstorm中专门有webpack的相关配置,默认的路径直接是项目根目录下的 webpack.config.js,但是我们用各种cli生成的项目中,webpack的配置一般都是在build下,导致 ...

  5. linux shell重定向

    http://note.youdao.com/noteshare?id=e944e6315d1566b3417e6f59305ddedc

  6. python爬虫requests过程中添加headers

    浏览器中打开页面,以edge为例,点击“查看源”或F12 第一步:点击上图中“网络”标签,然后刷新或载入页面 第二步:在右侧“标头”下方的“请求标头”中的所有信息都是headers内容,添加到requ ...

  7. vue.js react.js angular.js三者比较

    react和vue有许多相似之处,他们都有:1.使用虚拟DOM2.提供了响应式(reactive)和组件化(composable)的视图组件3.将注意力集中保持在核心库,而将其他功能如路由和全局状态管 ...

  8. Solr记录-solr基础内容

    Solr架构(体系结构) 在本章中,我们将讨论Apache Solr的架构. 下图显示了Apache Solr的体系结构的框图. Solr架构 - 构件块以下是Apache Solr的主要构建块(组件 ...

  9. POJ - 3436 ACM Computer Factory(最大流)

    https://vjudge.net/problem/POJ-3436 题目描述:  正如你所知道的,ACM 竞赛中所有竞赛队伍使用的计算机必须是相同的,以保证参赛者在公平的环境下竞争.这就是所有这些 ...

  10. Codeforces Round #477 (rated, Div. 2, based on VK Cup 2018 Round 3) E 贪心

    http://codeforces.com/contest/967/problem/E 题目大意: 给你一个数组a,a的长度为n 定义:b(i) = a(1)^a(2)^......^a(i), 问, ...