Java17——用数组和链表实现栈
栈的基本知识
栈(stack) 是一种以 “后进先出” 的方式存放数据的数据结构,如图所示 。
而栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。
允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。
数组实现栈的操作
数组实现栈的操作,根据栈的特点,我们需要知道栈顶所在的位置,栈的默认长度,当前栈的长度这样几个基本的数据,然后去实现栈的基本操作。
/**
基于数组实现的栈
*/
class ArrayStack extends Stack{
private static int DEFAULT_SIZE=10; //默认容量
private int top; //栈顶指针
private int[] data; //存储元素的容器
//创建一个栈使用默认容量
public ArrayStack(){
this(DEFAULT_SIZE);
}
//创建一个栈使用用户指定容量capacity
public ArrayStack(int capacity){
super();
this.top=-1;
this.data=new int[capacity];
}
//入栈一个元素e
public void push(int e){
if(top==data.length-1){
System.out.println("栈已满!无法入栈元素");
}
data[++top]=e;
}
//出栈一个元素
public int pop(){
if(isEmpty()){
System.out.println("栈已空!无法出栈元素");
return -1;//特殊含义 表示错误
}
return data[top--];
}
//判断栈是否为空
public boolean isEmpty(){
return this.top==-1;
}
//获取有效元素的个数
public int length(){
return this.top+1;
}
public String toString(){
StringBuilder sb=new StringBuilder();
sb.append('[');
for(int i=0;i<=top;i++){
sb.append(data[i]);
if(i==top)
return sb.append(']').toString();
sb.append(',');
sb.append(' ');
}
return "[]";
}
//获取当前栈的总容量
public int getCapacity(){
return data.length;
}
}
链表实现栈的操作
相对于数组,使用链表的好处是不用预先设置容量,因为链表在内存中的地址可以是不连续的,存在零散的空间即可使用链表。所以说链表是一种动态的数据结构。
链表由一系列节点节点组成,这些节点在内存中不必相连。每一个节点包含节点的元素以及该节点后继节点的链,我们称其为next链。不存在后继则将next设置为null。
访问链表,需要找到该链表的头节点。初始化每个链表时,均会设置一个头节点head。head中包含元素以及链向后继元的next。通过next,可以访问到head的后继元节点。
class LinkedStack extends Stack{//单向链表
private Node head; //链表的头指针
private int size; //链表的有效个数
public LinkedStack(){
this.head=new Node();
this.size=0;
}
public LinkedStack(int[] arr){
}
public void push(int e){
Node n=new Node();
n.data=e;
n.next=head.next;
head.next=n;
//head.next=new Node(e,head.next);
size++;
}
public int pop(){
if(isEmpty()){
System.out.println("栈已空!不能出栈元素!");
return -1;
}
Node n=head.next;
head.next=n.next;
n.next=null;
size--;
return n.data;
}
public int length(){
return size;
}
public boolean isEmpty(){
return size==0&&head.next==null;
}
public String toString(){
if(isEmpty()){
return "[]";
}
Node p=head.next;
StringBuilder sb=new StringBuilder();
sb.append('[');
while(true){
sb.append(p.data);
if(p.next==null){
sb.append(']');
break;
}else{
sb.append(", ");
p=p.next;
}
}
return sb.toString();
}
//内部类:在类里面定义的类
private class Node{
int data; //数据域
Node next;//指针域
Node(){
this(0,null);
}
Node(int data,Node next){
this.data=data;
this.next=next;
}
}
}