https://github.com/yzmaodeng/java-keypointknowledge/tree/master/src/main/java/com/zl/Datastructure/ArrayStack
public class MyArrayStack { //存储元素的数组,声明为Object类型能存储任意类型的数据 private Object[] elementData; //指向栈顶的指针 private int top; //栈的总容量 private int size; //默认构造一个容量为10的栈 public MyArrayStack(){ this .elementData = new Object[ 10 ]; this .top = - 1 ; this .size = 10 ; } public MyArrayStack( int initialCapacity){ if (initialCapacity < 0 ){ throw new IllegalArgumentException( "栈初始容量不能小于0: " +initialCapacity); } this .elementData = new Object[initialCapacity]; this .top = - 1 ; this .size = initialCapacity; } //压入元素 public Object push(Object item){ //是否需要扩容 isGrow(top+ 1 ); elementData[++top] = item; return item; } //弹出栈顶元素 public Object pop(){ Object obj = peek(); remove(); return obj; } //获取栈顶元素 public Object peek(){ if (top == - 1 ){ throw new EmptyStackException(); } return elementData[top]; } //判断栈是否为空 public boolean isEmpty(){ return (top == - 1 ); } //删除栈顶元素 public void remove( ){ //栈顶元素置为null elementData[top] = null ; this .top--; } /** * 是否需要扩容,如果需要,则扩大一倍并返回true,不需要则返回false * @param minCapacity * @return */ public boolean isGrow(int minCapacity) { // 如果当前元素压入栈之后总容量大于前面定义的容量,则需要扩容 if (minCapacity >= size) { // 定义扩大之后栈的总容量 int newCapacity = 0; // 栈容量扩大两倍(左移一位)看是否超过int类型所表示的最大范围 if ((size << 1) - Integer.MAX_VALUE > 0) { size= Integer.MAX_VALUE; } else { size = (size << 1);// 左移一位,相当于*2 } elementData = Arrays.copyOf(elementData, size); return true; } else { return false; }
} } |
测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //测试自定义栈类 ArrayStack //创建容量为3的栈,然后添加4个元素,3个int,1个String. @Test public void testArrayStack(){ My ArrayStack stack = new MyArrayStack( 3 ); stack.push( 1 ); //System.out.println(stack.peek()); stack.push( 2 ); stack.push( 3 ); stack.push( "abc" ); System.out.println(stack.peek()); stack.pop(); stack.pop(); stack.pop(); System.out.println(stack.peek()); } |
结果:
利用栈实现字符串逆序
我们知道栈是后进先出,我们可以将一个字符串分隔为单个的字符,然后将字符一个一个push()进栈,在一个一个pop()出栈就是逆序显示了。如下:
将 字符串“how are you” 反转!!!
ps:这里我们是用上面自定的栈来实现的,大家可以将ArrayStack替换为JDK自带的栈类Stack试试
1 2 3 4 5 6 7 8 9 10 11 12 13 | //进行字符串反转 @Test public void testStringReversal(){ My ArrayStack stack = new MyArrayStack(); String str = "how are you" ; char [] cha = str.toCharArray(); for ( char c : cha){ stack.push(c); } while (!stack.isEmpty()){ System.out.print(stack.pop()); } } |
利用栈判断分隔符是否匹配
写过xml标签或者html标签的,我们都知道<必须和最近的>进行匹配,[ 也必须和最近的 ] 进行匹配。
比如:<abc[123]abc>这是符号相匹配的,如果是 <abc[123>abc] 那就是不匹配的。
对于 12<a[b{c}]>,我们分析在栈中的数据:遇到匹配正确的就消除
最后栈中的内容为空则匹配成功,否则匹配失败!!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | //分隔符匹配 //遇到左边分隔符了就push进栈,遇到右边分隔符了就pop出栈,看出栈的分隔符是否和这个有分隔符匹配 @Test public void testMatch(){ My ArrayStack stack = new MyArrayStack( 3 ); String str = "12<a[b{c}]>" ; char [] cha = str.toCharArray(); for ( char c : cha){ switch (c) { case '{' : case '[' : case '<' : stack.push(c); break ; case '}' : case ']' : case '>' : if (!stack.isEmpty()){ char ch = stack.pop().toString().toCharArray()[ 0 ]; if (c== '}' && ch != '{' || c== ']' && ch != '[' || c== ')' && ch != '(' ){ System.out.println( "Error:" +ch+ "-" +c); } } break ; default : break ; } } } |