棧是一種先進後出的數據結構,但是很多地方都是用C和C++的方式來講解
下面就記錄一下在java裏面怎麼用:
- 第一種使用數組作爲存儲結構
- 第二種使用鏈表作爲存儲結構
使用數組作爲存儲結構過程中需要擴容,而使用鏈表不會。
下面代碼給出了使用數組和鏈表作爲儲存結構的棧,並且給出了一個關於括號匹配的棧的應用。
package com.zq.datastruct.linkedlist;
import java.util.Arrays;
/**
* Created by zhengshouzi on 2015/11/16.
*/
public class StackTest {
public static void main(String[] args) {
System.out.println("------------------------arrayStack-------------------------------------");
ArrayStack arrayStack = new ArrayStack();
arrayStack.push(22);
arrayStack.push(32);
arrayStack.pop();
arrayStack.push(100);
arrayStack.push(76);
System.out.println(arrayStack.toString());
arrayStack.push(444);
System.out.println(arrayStack.toString());
System.out.println("------------------------linkedListStack-------------------------------------");
LinkedListStack linkedListStack = new LinkedListStack();
linkedListStack.push(22);
linkedListStack.push(32);
linkedListStack.pop();
linkedListStack.push(100);
linkedListStack.push(76);
System.out.println(linkedListStack.toString());
linkedListStack.push(444);
System.out.println(linkedListStack.toString());
System.out.println("----------------------------括號匹配應用------------------------------------------------");
System.out.println("表達式:[(23+12)]*[2/(3-7)] is " +MathExpression.isLegel("[(23+12)]*[2/(3-7)]"));
}
}
interface Stack<T> {
/**
* 判斷棧是否爲空
*/
boolean isEmpty();
/**
* 清空棧
*/
void clear();
/**
* 棧的長度
*/
int length();
/**
* 數據入棧
*/
boolean push(T data);
/**
* 數據出棧
*/
T pop();
}
class ArrayStack<T> implements Stack<T> {
private Object[] data = new Object[3];
private int size = 0;
public boolean isEmpty() {
return size == 0;
}
public void clear() {
// 將數組中的數據置爲null, 方便GC進行回收
for (int i = 0; i < size; i++) {
data[size] = null;
}
size = 0;
}
public int length() {
return size;
}
public boolean push(T k) {
// 判斷是否需要進行數組擴容
if (size >= data.length) {
resize();
}
System.out.println("push: " + k);
data[size++] = k;
return true;
}
/**
* 數組擴容
*/
private void resize() {
System.out.println("數組空間不夠,擴容");
Object[] temp = new Object[data.length * 2];
for (int i = 0; i < size; i++) {
temp[i] = data[i];
data[i] = 0;
}
data = temp;
}
public T pop() {
if (size == 0) {
return null;
}
System.out.println("pop:"+(T)data[--size]);
return (T)data[size];
}
@Override
public String toString() {
return "ArrayStack{" +
"data=" + Arrays.toString(data) +
", size=" + size +
'}';
}
}
class LinkedListStack<T> implements Stack<T> {
private StackNode top;
private int size = 0;
public boolean isEmpty() {
return size == 0;
}
public void clear() {
top=null;
size = 0;
}
public int length() {
return size;
}
public boolean push(T k) {
StackNode newNode = new StackNode();
newNode.setData(k);
newNode.setPre(top);
top = newNode;
size++;
System.out.println("push: " +k);
return true;
}
public T pop() {
if (size == 0) {
return null;
}
T data = top.getData();
System.out.println("pop:"+data);
top= top.getPre();
size--;
return data;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
StackNode temp = top;
while (temp!=null){
sb.append(temp.getData()+" ");
temp=temp.getPre();
}
return "LinkedListStack{" +
"stack=" + sb.toString() +
", size=" + size +
'}';
}
private class StackNode{
private T data;
private StackNode pre;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public StackNode getPre() {
return pre;
}
public void setPre(StackNode pre) {
this.pre = pre;
}
}
}
class MathExpression{
public static boolean isLegel(String str) {
Stack<Character> stack = new LinkedListStack<>();
char[] arr = str.toCharArray();
for (char c : arr) {
//只入棧,出棧括號
if (c=='[' || c==']' || c=='(' || c==')'){
Character temp = stack.pop();
// 棧爲空時只將c入棧
if (temp == null) {
stack.push(c);
} else if (temp == '[' && c == ']') {
// 配對時c不入棧
} else if (temp == '(' && c == ')') {
// 配對時c不入棧
}
else {
// 不配對時c入棧
stack.push(temp);
stack.push(c);
}
}
}
return stack.isEmpty();
}
}