1.数组实现固定大小的栈
- 思路:定义一个数组外加一个变量size,size变量的意义为记录当前栈存储元素的位置
public static class ArrayStack {
private Integer[] array;
private Integer size;
public ArrayStack(int initSize) {
if (initSize < 0) {
throw new IllegalArgumentException("数组长度不能小于0");
}
array = new Integer[initSize];
size = 0;
}
//查看栈顶元素
public Integer peek() {
if (size == 0) {
return null;
}
return array[size - 1];
}
//压栈
public void push(int num) {
if (size == array.length) {
throw new ArrayIndexOutOfBoundsException("栈已经满了");
}
array[size++] = num;
}
//弹出栈
public Integer pop() {
if (size == 0) {
throw new ArrayIndexOutOfBoundsException("栈为空");
}
return array[--size];
}
}
2. 数组实现固定大小的队列
- 思路:定义三个变量,start用来记录首位置的元素,end用来记录元素的存储位置,size用来记录数组中还有几个剩余位置.
public static class ArrayQueue {
private Integer[] arr;
private Integer start;
private Integer end;
private Integer size;
//初始化数组
public ArrayQueue(int initSize) {
if (initSize < 0) {
throw new IllegalArgumentException("数组长度不能小于0");
}
arr = new Integer[initSize];
size = 0;
start = 0;
end = 0;
}
//查看队列的首元素
public Integer peek() {
if (size == 0) {
return null;
}
return arr[start];
}
//往数组中存入元素
public void push(Integer num) {
if (size == arr.length) {
//如果size为数组长度,则代表队列已满,抛出异常
throw new ArrayIndexOutOfBoundsException("队列以满");
}
//如果可以进行到这里,说明数组中有剩余位置
//首先size++
size++;
//end所指的位置为新进入的元素的位置
arr[end] = num;
//如果end指向数组中最后一个位置,end指向0位置,否则end+1
end = end == arr.length-1 ? 0 : end+1;
}
//获取队列的第一个元素
public Integer pop() {
//如果size==0,说明队列中没有元素,抛出异常
if (size == 0) {
throw new ArrayIndexOutOfBoundsException("队列已经为空");
}
//程序执行到这里,说明size>0
//首先size--
size--;
//记录start所指的位置
int tmp = start;
//判断start所指的位置是否为数组的最后一个位置,如果是,start从0位置开始,否则start+1
start = start == arr.length -1? 0 : start + 1;
return arr[tmp];
}
}
3. 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返 回栈中最小元素的操作。
1.pop、push、getMin操作的时间复杂度都是O(1)。
2.设计的栈类型可以使用现成的栈结构。
思路:设计两个栈,同时压栈,第一个栈push的元素全部存入,第二个栈先存入第一个元素,当存入第二个元素时,与第个元素相比较,如果第一个元素较小,则不存入第二个元素,将第一个元素再次存入一遍,依次类推…,这样第二个栈的 栈首就为最小值
public static class MyStack{
private Stack<Integer> stackData;
private Stack<Integer> stackMin;
//初始化栈
public MyStack() {
this.stackData = new Stack<Integer>();
this.stackMin = new Stack<Integer>();
}
public void push(int newNum) {
if (this.stackMin.isEmpty()) {
this.stackMin.push(newNum);
} else if (newNum < this.getmin()) {
//如果新元素小于栈首元素,则压入新元素
this.stackMin.push(newNum);
} else {
//如果栈首元素比当前元素小,则再次压入栈首元素
int newMin = this.stackMin.peek();
this.stackMin.push(newMin);
}
//另一个栈依次压入元素
this.stackData.push(newNum);
}
public int pop() {
if (this.stackData.isEmpty()) {
throw new RuntimeException("栈为空");
}
//弹出栈首元素两个栈同时进行,保证stackMin中为剩余元素的最小值
this.stackMin.pop();
return this.stackData.pop();
}
public int getmin() {
if (this.stackMin.isEmpty()) {
throw new RuntimeException(栈为空.");
}
return this.stackMin.peek();
}
}