栈是一种只允许在一端(top)进行插入和删除的线性表,特点是先进后出。
我们接下来要介绍栈的几个基本操作,判断栈空、判断栈满。出栈。进栈、给栈扩容等等。
1.栈的顺序存储结构
//顺序链表
class SqStack{
private int[] stack;
private int top;
//开辟10个元素的空间
public SqStack(){
// this.stack = new int[10];
// this.top =0 ;
this(10);
}
public SqStack(int size){
this.stack = new int[size];
this.top = 0;
}
//入栈
public void push(int val){
if(full())
resize(); //如果栈满则扩容
this.stack[this.top++] = val;
}
//出栈
public void pop(){
if(empty())
return;
this.top--;
}
//返回栈顶元素
public int top(){
return this.stack[this.top-1];
}
//判断是否栈空
public boolean empty(){
return this.top == 0;
}
//判断是否栈满
public boolean full(){
return this.top == this.stack.length;
}
//栈的扩容,一次扩容两倍
public void resize(){
this.stack = Arrays.copyOf(stack, top*2);
}
//用Arrays.copyOf函数进行扩容,利用拷贝的特性
}
2.栈的链式存储结构
//定一个节点并初始化节点
class Node{
int value;
Node next;
Node(){
this(0);
}
Node(int value){
this.next = null;
this.value = value;
}
}
class LinkList{
Node head;
//定义一个链表
public LinkList(){
head = new Node(0);
}
//判断是否为空
public boolean empty(){
return head.next == null;
}
//头插法插入节点
public void insertHead(int val){
Node n = new Node(val);
n.next = head.next;
head.next = n;
}
//尾插法插入节点
public void insertTail(int val){
Node ptail = head;
while(ptail.next != null){
ptail = ptail.next;
}
ptail.next = new Node(val);
}
//删除节点
public void delete(int val){
Node pcur = head.next;
Node ppre = head;
while(pcur != null){
if(pcur.value == val){
ppre.next = pcur.next;
break;
}
ppre = pcur;
pcur = pcur.next;
}
}
//自己实现toString方法
public String toString(){
StringBuilder builder = new StringBuilder();
Node n = head.next;
while(n != null){
builder.append(n.value + " ");
n = n.next;
}
return builder.toString();
}
}
顺序表与链表比较,顺序表用数组存储数据,更容易实现且操作简单,但做插入删除操作时需大量移动数据,效率较低。
链表采用栈的形式存取数据,与顺序表的优缺点刚好相反。