1.1 概念与结构
特点:先进后出 LIFO(Last In First Out)
栈也是一种特殊的线性表,一种操作受限制的线性表,只允许在一端插入与删除数据。
1.1.1 栈的基本操作
栈顶:数据插入与删除的一端叫做栈顶,另一端叫做栈底
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
出栈:栈的删除操作叫做出栈。出数据也在栈顶
栈是一种“操作受限”的线性表,只允许在一端插入和删除数据
应用:撤销键
1.1.2 栈的储存结构:
顺序栈:基于数组实现的
链式栈:基于链表实现
1.2 栈的实现
push()//入栈
pop()//出栈
peek()//返回栈顶元素
1.2.1栈接口
package com.DS.StackDemo;
/**
* @Name: 栈接口
* @Author:ZYJ
* @Date:2019-07-23-20:32
* @Description:
*/
public interface IStack<T> {
//入栈
boolean push(T t);
//出栈
T pop();
//返回栈顶元素,但不出栈
T peek();
//当前栈的元素个数
int getSize();
//栈是否为空
boolean isEmpty();
}
1.2.1 基于数组的栈
package com.DS.StackDemo;
import java.util.Arrays;
import java.util.Deque;
/**
* @Name: 基于数组的栈 顺序栈
* @Author:ZYJ
* @Date:2019-07-23-20:40
* @Description:
*/
//泛型的实现:接口继续保持泛型
public class ArrayStackImpl<T> implements IStack<T> {
//存放数据
private Object[] elementData;
//最多存放元素个数
private int maxSize;
//当前栈中的元素个数
private int currentSize;
public ArrayStackImpl(int maxSize) {
this.maxSize = maxSize;
elementData = new Object[maxSize];
}
/**
* 入栈
* @param t
* @return
*/
@Override
public boolean push(T t) {
//栈已满
if(currentSize==maxSize){
//扩容
int oldSize = maxSize;
int newSize = oldSize<<1;
if(newSize+8>Integer.MAX_VALUE){
System.err.println("栈太大");
return false;
}
maxSize=newSize;
elementData= Arrays.copyOf(elementData,maxSize);
}
elementData[currentSize++]=t;
return true;
}
/**
* 出栈
* @return 栈顶元素
*/
@Override
public T pop() {
if(isEmpty()){
System.out.println("栈为空");
return null;
}
return (T) elementData[--currentSize];
}
/**
* 返回栈顶元素 但不出栈
* @return
*/
@Override
public T peek() {
if(isEmpty()){
System.out.println("栈为空");
return null;
}
return (T) elementData[currentSize-1];
}
/**
* 返回当前栈的元素个数
* @return
*/
@Override
public int getSize() {
return currentSize;
}
/**
* 栈的判空操作
* @return
*/
@Override
public boolean isEmpty() {
return currentSize==0;
}
}
1.2.2 基于链表的栈
package com.DS.StackDemo;
/**
* @Name: 基于链表的栈
* @Author:ZYJ
* @Date:2019-07-23-20:57
* @Description:
*/
public class LinkedStackImpl<T> implements IStack<T> {
private Node top;//栈顶元素
private int currentSize;//当前栈的元素数量
/**
* 节点类
*/
private class Node {
private T t;
private Node next;
public Node(T t, Node next) {
this.t = t;
this.next = next;
}
}
/**
* 入栈
*
* @param t
* @return
*/
@Override
public boolean push(T t) {
//头插 左进
//创建新节点
Node newNode = new Node(t, null);
if (top == null) {//空
top = newNode;
} else {
newNode.next = top;
top = newNode;
}
currentSize++;
return true;
}
/**
* 出栈
*
* @return
*/
@Override
public T pop() {
if (isEmpty()) {
System.err.println("当前栈为空");
return null;
}
T result = top.t;
top=top.next;
currentSize--;
return result;
}
/**
* 返回栈顶元素 但不出栈
* @return
*/
@Override
public T peek() {
if(isEmpty()){
System.err.println("当前栈为空");
return null;
}
return top.t;
}
@Override
public int getSize() {
return currentSize;
}
@Override
public boolean isEmpty() {
return currentSize == 0;
}
}
1.3 栈的应用
借助栈实现 十进制—>二进制
package Test.StackTest;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;
/**
* @Name: 借助栈实现进制转换
* @Author:ZYJ
* @Date:2019-07-27-15:08
* @Description:
*/
public class TestConvert {
public static void main(String[] args) {
int num =100;
Deque stack = new LinkedList();
while (num>0){
stack.push(num%2);
num=num/2;
}
System.out.print(num+"--->");
while (!stack.isEmpty()){
System.out.print(stack.pop());
}
}
}