1 栈是限定仅在表尾进行插入和删除操作的线性表,允许插入和删除的一端称为栈顶、另外一端称为栈底。不含任何元素的栈被称为空栈。栈中的元素除了具有线性关系外,还有先进后出的性质。
JDK源码栈的实现,采用数组+指针的形式。
入栈,将数据添加到最大的index处。
public E push(E item) {
addElement(item);
return item;
}
出栈,返回最大index处的数据。然后将index处数据置为空,方便gc回收。
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
public class SequentialStackCustom<E> {
/**
* 栈的最大元素个数
*/
private static final Integer MAX_SIZE=100;
/**
* 元素存储空间
*/
private Object[] data;
/**
* 头指针
*/
private Integer top=-1;
public SequentialStackCustom(){
data=new Object[MAX_SIZE];
}
/**
* 入栈操作
* @param x 入栈元素
*/
public void push(E x)
{
if(top>=MAX_SIZE)
{
System.out.println("栈已满");
}
else
{
data[++top]=x;
}
}
/**
* 数据出栈操作
* @return 最顶端的数据
*/
@SuppressWarnings("unchecked")
public E pop()
{
return (E)data[top--];
}
/**
* 返回当前栈中元素个数
* @return 元素个数
*/
public Integer size()
{
return top+1;//top是从0开始的
}
/**
* 读取首元素
* @return
*/
@SuppressWarnings("unchecked")
public E getTopData()
{
return (E)data[top];
}
/**
* 获取头指针的指向
* @return
*/
public Integer getTop(){
return top;
}
/**
* 清空栈
*/
public void clear()
{
top=-1;
}
/**
* 是否为空栈
* @return 为空栈则true,不为空则为false
*/
public boolean isEmpty()//判断栈是否为空,若为空返回true,否则,返回false
{
return top==-1;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SequentialStackCustom<Integer> ssc=new SequentialStackCustom<Integer>();
ssc.push(1);
ssc.push(2);
ssc.push(3);
ssc.push(4);
while(ssc.getTop()>=0)
{
System.out.println(ssc.pop());
}
}
}
在网上观看大神的博客,使用泛型数组来存储的一种方法。
public class ArrayOfGeneric4<T> {
T[] ts;
public ArrayOfGeneric4(Class<T> type, int size) {
ts = (T[]) Array.newInstance(type, size);
}
public T get(int index) {
return ts[index];
}
public T[] rep() {
return ts;
}
public void set(int index, T t) {
ts[index] = t;
}
public static void main(String[] args) {
ArrayOfGeneric4<Integer> aog2 = new ArrayOfGeneric4<Integer>(Integer.class, 10);
Object[] objs = aog2.rep();
for (int i = 0; i < 10; i++) {
aog2.set(i, i);
System.out.println(aog2.get(i));
}
try {
Integer[] strs = aog2.rep();
System.out.println("user Array.newInstance to create generci of array was successful!!!!! ");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
通过看源码和大神的博客,发现使用泛型底层还是转为Objetc类型,决定数据存储使用的Object类型的数组,而返回中则用强制类型转换将Objetc类型的数组转为E类型。
参考博客:
http://www.cnblogs.com/scutwang/articles/3735219.html
http://blog.csdn.net/z69183787/article/details/41450973
http://www.cnblogs.com/exmyth/p/4598971.html
2 栈的链接存储
链接存储,从小到上,节点结构为一个指针指向向下的一个节点,一个数据域。定义了一个头指针,初始指向空,非空情况下指向一个栈顶的一个节点。为空指向空。
/**
* @Author: ShipTang
* @Description: 栈重写
* @Date: 2021/8/11 16:48
*/
public class DequeRewrite<E> {
/**
* 空节点,给头指针初始化指向使用,防止出现空指针
*/
private final Node<E> emptyNode = new Node<>(null);
/**
* 头指针
*/
private Node<E> topNode;
public DequeRewrite() {
this.topNode = emptyNode;
}
public void push(E e) {
this.topNode = new Node<>(e, topNode);
}
public E pull() {
Node<E> resultNode = this.topNode;
this.topNode = resultNode.nextNode;
//断开改节点与其他节点的联系
resultNode.nextNode = null;
return resultNode.e;
}
public void printDeque() {
Node<E> node = this.topNode;
while (node != null && node != emptyNode) {
System.out.println(node.e);
node = node.nextNode;
}
}
private static class Node<E> {
private E e;
private Node<E> nextNode;
public Node(E e) {
this.e = e;
}
public Node(E e, Node<E> nextNode) {
this.e = e;
this.nextNode = nextNode;
}
}
}