栈定义
栈(Stack)是限定仅在表尾进行插入和删除操作的线性表.
- 我们把允许插入和单楚楚的一端称为栈顶(top), 另一端称为栈底(bottom),不含任何数据元素的栈称为空栈.
- 栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构
数组实现思路
- 线性表当数组来实现时,我们拿
下标0
的一端作为栈底比较好,因为首元素都在栈底,变化最小,所以让他作为栈底 - 定义一个变量
top
,指示栈顶元素都在数组中的位置,这top
可以来回移动,意味着栈顶的top可以变大变小,但不能超出数组的长度 - 若存储栈的长度为
StackSize
,则栈顶的位置top
必须小于StackSize
. - 当栈存在一个元素时,
top
等于0
,因此通常把空栈的判定条件定为top= -1
数组实现代码
package com.company;
/**
* @Author: wsh
* @Date: 2020/8/2
*/
public class StackTest {
public static void main(String[] args) {
ArrStackList arrStackList = new ArrStackList();
String data = "31,21,17";
arrStackList.init(data.split(","));
arrStackList.out("初始化");
arrStackList.push(3);
arrStackList.out("push 3 后");
int pop = arrStackList.pop();
arrStackList.out("出栈"+pop);
}
}
class ArrStackList{
ArrStack arrStack = new ArrStack();
public int pop() {
if (arrStack.top ==-1) {
System.out.println("栈已空,失败");
return -1;
}
int datum = arrStack.data[arrStack.top];
arrStack.top--;
return datum;
}
public void push(int value) {
if (arrStack.top + 1 == arrStack.data.length) {
System.out.println("入栈失败,已满");
return;
}
arrStack.top++;
arrStack.data[arrStack.top] = value;
}
public void init(String[] data) {
for (int i=0;i<data.length;) {
int value = Integer.parseInt(data[i]);
arrStack.data[i] = value;
arrStack.top=i++;
}
System.out.println();
}
public void out(String str) {
System.out.println(str);
int[] data = arrStack.data;
int top = arrStack.top;
for (int i =top; i >=0; i--) {
System.out.print(data[i]+" ");
}
System.out.println("\n======");
}
}
class ArrStack {
private int MaxLength=10;
public int[] data = new int[MaxLength];
public int top=-1;
}
输出
初始化
17 21 31
======
push 3 后
3 17 21 31
======
出栈3
17 21 31
======
数组感觉
- 这个数据结构编写相对简单的多,多了一个变量记录数组的最后一个值。
书本中有两栈共享空间章节,感觉实用性不大,就没有敲.在此略过.(偷个懒)
代码和逻辑都比较简单,顺便把链表方式也一并放入
链表存储的实现思路
栈的链式存储结构,简称为链栈
栈只是栈顶用来做插入和删除操作,栈顶放在链表的头部还是尾部呢?
由于单链表有头指针,而栈顶指针也是必须的,干嘛不让他们两个合二为一呢,所以比较好的办法就是把栈顶放在单链表的头部,另外,都有了栈顶在头部了,单链表中比较常用的头结点也就失去了意义,通常对于链栈来说不需要头结点的.
特殊点:
- 对于空栈来说,链表的原定义是头指针指向null,那么链栈的空就是
top=NULL
的时候 - 链栈的大部分操作都和单链表相似,只是插入和删除的时候,特殊一些,还要照顾栈对象的
top
链表存储代码实现
package ***;
/**
* @Author: wsh
*/
public class LinkStackTest {
public static void main(String[] args) {
LinkStackList linkStackList = new LinkStackList();
String data = "31,21,17,16,55";
linkStackList.init(data.split(","));
linkStackList.out("初始化");
linkStackList.push(100);
linkStackList.out("push");
int pop = linkStackList.pop();
System.out.println("出栈"+pop);
linkStackList.out("");
}
}
class LinkStackList{
LinkStack linkStack = new LinkStack();
public void push(Integer value) {
Link link = new Link();
link.data = value;
link.nextNode=linkStack.top;
linkStack.top =link;
linkStack.count++;
}
public int pop() {
Link top = linkStack.top;
linkStack.top = top.nextNode;
linkStack.count--;
return top.data;
}
public void init(String[] data) {
for (int i = 0; i < data.length; i++) {
push(Integer.parseInt(data[i]));
}
}
public void out(String str) {
Link top = linkStack.top;
int count = linkStack.count;
System.out.println(str);
while (count > 0) {
System.out.print(top.data+" ");
top = top.nextNode;
count--;
}
System.out.println("\n=========");
}
}
/**
* 链栈
*/
class LinkStack{
public Link top;
public int count;
}
/**
* 链表对象
*/
class Link{
public int data;
public Link nextNode;
}
输出
初始化
55 16 17 21 31
=========
push
100 55 16 17 21 31
=========
出栈100
55 16 17 21 31
=========
链表感觉
在掌握了链表的初始化,插入这些基本的操作后,这个业务逻辑比较简单.就是弄不弄的事