Definition of stack
Last-in first-out, first-in-last-out, is a linear table with limited operations, allowing only one end to insert and delete data. Most of the scenes that use the stack can be replaced by arrays or linked lists, but arrays and linked lists expose too many operation interfaces, which seem to be very flexible, but the corresponding risks increase and become more uncontrollable.
Constant volume stack
That is, the size of a stack is specified when it is created
Create a constant volume stack
Unused paradigm
package com.pjh.Stack;
public class FixedCapacityStack {
/*定义一个数组*/
private String[] a;
/*定义一个大小*/
private int N;
/*有参构造方法*/
public FixedCapacityStack(int n) {
a=new String[n];
}
/*判断数组是否为空*/
public boolean isEmpty(){
return N==0;
}
/*返回数组的大小*/
private int size(){
return N;
}
/*出栈*/
public String pop(){
return a[--N];
}
/*入栈*/
public void push(String item){
a[N++]=item;
}
}
Use paradigm
Note: It is not allowed to create a generic array due to some historical and technical reasons
Implementation code
package com.pjh.Stack;
public class FixedCapacityStack2<Item> {
/*定义一个数组*/
private Item a[];
/*定义一个大小*/
private int N;
/*有参构造方法*/
public FixedCapacityStack2(int n) {
a=(Item[]) new Object[n];
}
/*判断数组是否为空*/
public boolean isEmpty(){
return N==0;
}
/*返回数组的大小*/
private int size(){
return N;
}
/*出栈*/
public Item pop(){
return a[--N];
}
/*入栈*/
public void push(Item item){
a[N++]=item;
}
}
Code optimization
Question 1
Problem overview
Choosing an array to represent the contents of the stack must pre-estimate the maximum capacity of the stack. In Java, the size of the array cannot be changed once it is created, so the space used by the stack can only be part of this maximum capacity. Use cases with large capacity will waste a lot of memory when the stack is empty or almost empty. For example, a transaction system may involve billions of transactions and a collection of thousands of transactions. Even though this system generally limits each transaction to appear in only one set, the use case must ensure that all sets have the ability to store all transactions. On the other hand, if the set becomes larger than the array, the use case may overflow . Therefore, we need a method to detect whether the stack is full, and a method to expand the stack. This is actually the idea of a dynamic array
solution
The isFull() method determines whether the stack is full
/*判满方法,只供内部方法调用*/
private void isFull(){
/*如果满了则调用数组扩容方法,扩容的倍数可以根据实际的需要调节*/
if (N==a.length){
resize();
}
}
resize() expansion method
private void resize(){
int newCapacity= (int) (a.length * 2);
int lastCapacity=a.length;
Item[] newArray = (Item[]) new Object[newCapacity];
for (int i = 0; i < lastCapacity; i++)
newArray[i]=a[i];
/*将a数组的首地址指向newArray数组*/
a=newArray;
}
Question 2
Problem overview 2
If we pop a large amount of data during use, but the previous array space is very large, so we also need to dynamically reduce the stack capacity to maximize the memory usage
solution
When calling the pop() pop function, we first delete the element at the top of the stack, and then if the array is too large, we will halve the length of the array
Stack usage scenarios
Take the browser we usually use as an example. When we click on multiple web pages on the same page, we often use the browser’s back and forward buttons to return to the previous opened page and the next opened page.
For example, we have opened in the unified page
taobao.com
jd.com
tx.com
When we click the left arrow, we return to jd.com
When we click the right arrow again, we return to taobao.com
This operation can be achieved by using the stack
**
diagram
When we click the left arrow, we return to jd.com
When we click the right arrow again, we return to taobao.com
Similar application scenarios also have the software's undo and recovery function