栈——先进后出:是一种运算受限的线性表,仅在表尾进行插入和删除操作,这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,是把新元素放到栈顶元素的上面,使之成为新的栈顶元素,从一个栈删除元素又称作出栈或退栈,是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
栈与堆的区别:
①栈(操作系统):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。栈使用一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放。
②堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。
一个简单的入栈出栈:
public class MyStackTest<T> {
private T element[];
private int size;
private int top;
public MyStackTest(int size) {
this.size = size;
this.element = (T[]) new Object[size];
this.top = 0;
}
public boolean isEmpty() {
if (top < 0) {
return true;
}
return false;
}
public boolean isFull() {
if (top > size) {
return true;
}
return false;
}
public void push(T value) {
if (isFull()) {
//栈满
return;
} else {
element[++top] = value;//栈顶指针加1并赋值
}
}
public T pop() {
if (isEmpty()) {
//栈为空
return null;
} else {
T value = element[top];//取出栈顶元素
--top;//栈顶指针-1
return value;
}
}
public T peek() {
if (isEmpty()) {
return null;
} else {
T value = element[top];
return value;
}
}
public static void main(String[] args) {
MyStackTest<Integer> stack = new MyStackTest<Integer>(10);
// System.out.println(stack.isEmpty());
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
int popArr[]=new int[10];
System.out.println("此时栈顶元素为"+stack.peek());
System.out.println("出栈顺序:");
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
// System.out.println("此时栈顶元素为"+stack.peek());
}
}
判断所给序列是否为合理的出栈顺序,例如1,2,3,4,5入栈,出栈顺序可能为1,2,5,4,3或3,2,1,5,4等。
import java.util.Stack;
public class isOutOrder<T> {
private T[] arr;
private T[] order;
private static final int initSIZE = 10;
public isOutOrder() {
arr = (T[]) new Object[initSIZE];
order = (T[]) new Object[initSIZE];
}
public static <T extends Comparable<T>> boolean isOrder(T[] arr, T[] order) {
Stack<T> stack = new Stack<>();
if (arr.length != order.length || arr.length <= 0 || order.length <= 0) {
return false;
}
int i = 0, j = 0;
for (i = 0; i < arr.length; i++) {
stack.push(arr[i]);//入栈
while((!stack.empty()) && (stack.peek() == order[j])) {//如果栈不为空且当前栈顶元素和序列元素一致则出栈
stack.pop();
j++;//j往后移
}
}
if (stack.empty()) {
return true;//直到栈内元素全部出栈即为合理序列
} else {
return false;
}
}
public static void main(String[] args) {
System.out.println(isOrder(new Integer[]{1, 2, 3, 4, 5}, new Integer[]{1, 2, 5, 4, 3}));//t
System.out.println(isOrder(new Integer[]{1, 2, 3, 4, 5}, new Integer[]{3, 2, 1, 5, 4}));//t
System.out.println(isOrder(new Integer[]{1, 2, 3, 4, 5}, new Integer[]{2, 3, 5, 1, 4}));//f
}
}
两个栈模拟一个队列(队列的特点是先进先出,因此头插尾删和头删尾插即可,此处使用头删尾插)
import java.util.Stack;
public class twoStackToQueue<T>{
Stack<T> stack1 = new Stack<T>();
Stack<T> stack2 = new Stack<T>();
public void addTail(T value)
{
stack1.push(value);
}
public T deleteHead() {
if (twoSize() != 0) {
if (stack2.isEmpty())
mergeTwoStack();
return stack2.pop();
} else {
return null;
}
}
public void mergeTwoStack(){
while (!stack1.isEmpty())
stack2.push(stack1.pop());
}
public int twoSize() {
return stack1.size() + stack2.size();
}
public static void main(String[] args) {
twoStackToQueue stq = new twoStackToQueue();
stq.addTail(1);
stq.addTail(2);
stq.addTail(3);
stq.addTail(4);
stq.addTail(5);
System.out.println("顺序:");
System.out.println(stq.deleteHead());
System.out.println(stq.deleteHead());
System.out.println(stq.deleteHead());
System.out.println(stq.deleteHead());
System.out.println(stq.deleteHead());
}
}
括号匹配问题(遇到左括号则入栈,遇到右括号判断是否有对应左括号)
import java.util.Stack;
public class Brackets {
public void Match(String string) {
Stack<Character> stack = new Stack<>();
if (string == "") {
System.out.println("不匹配");
}
for (int i = 0; i < string.length(); i++) {
switch (string.charAt(i)) {
case '(':
stack.push(string.charAt(i));
break;
case ')':
if (!stack.empty() && stack.peek() == '(') {
stack.pop();
}
break;
case '[':
stack.push(string.charAt(i));
break;
case ']':
if (!stack.empty() && stack.peek() == '[') {
stack.pop();
}
case '{':
stack.push(string.charAt(i));
break;
case '}':
if (!stack.empty() && stack.peek() == '{') {
stack.pop();
}
}
}
if (stack.empty()) {
System.out.println("匹配");
}
else{
System.out.println("不匹配");
}
}
public static void main(String[] args) {
String s1 = "{(1+2)+3*4}";
String s2 = "{(1+2)+3*4]";
Brackets b = new Brackets();
b.Match(s1);
b.Match(s2);
}
}