Java栈的实现(顺序栈、链式栈)及栈的应用

1. 顺序栈的实现

 顺序栈实现1
package lang;

import java.io.Serializable;
import java.util.Arrays;

/** 
 * @ClassName: ArrayStack
 * @Description: 顺序栈
 * @date 2014年1月20日 上午8:47:19
 * @param <T>
 */
public class ArrayStack<T> implements Serializable {

  /**
   * @Fields serialVersionUID : TODO
   */
  private static final long serialVersionUID = 74027006708386243L;

  private Object[] elementData;//定义一个数组用于保存顺序栈的元素

  private int size = 0;//保存顺序栈中元素的当前个数

  private int capacity;//保存数组的长度

  public ArrayStack() {
    elementData = new Object[10];//默认长度为10的栈    
  }

  public ArrayStack(int initSize) {
    elementData = new Object[initSize];//默认长度为10的栈
  }

  public ArrayStack(T element) {
    this();
    elementData[0] = element;
    size++;
  }

  public ArrayStack(T element, int initSize) {
    this.capacity = initSize;
    elementData = new Object[capacity];
    elementData[0] = element;
    size++;
  }

  /**
   * @Title: size     
   * @Description: 栈长度    
   * @return
   */
  public int size() {
    return size;
  }

  /**
   * @Title: push     
   * @Description: 入栈    
   * @param element
   */
  public void push(T element) {
    ensureCapacity(size + 1);
    elementData[size++] = element;
  }

  private void ensureCapacity(int minCapacity) {
    //如果数组的原有长度小于目前所需的长度
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
      int newCapacity = (oldCapacity * 3) / 2 + 1;
      if (newCapacity < minCapacity)
        newCapacity = minCapacity;
      // minCapacity is usually close to size, so this is a win:
      elementData = Arrays.copyOf(elementData, newCapacity);
    }

  }

  /**
   * @Title: pop     
   * @Description: 出栈    
   * @return
   */
  public T pop() {
    if (!isEmpty()) {
      T oldValue = (T) elementData[size - 1];
      //释放栈顶元素
      elementData[--size] = null;
      return oldValue;
    } else {
      return null;
    }
  }

  /**
   * @Title: peek     
   * @Description: 返回栈顶元素,但不删除栈顶元素    
   * @return
   */
  public T peek() {
    if (!isEmpty()) {
      return (T) elementData[size - 1];
    } else {
      throw new IndexOutOfBoundsException("空栈异常");
    }
  }

  /**
   * @Title: empty     
   * @Description: 判断顺序栈是否为空栈    
   * @return
   */
  public boolean isEmpty() {
    return size == 0;
  }

  /**
   * @Title: clear     
   * @Description: 清空顺序栈
   */
  public void clear() {
    //将底层数组所有元素赋为null
    Arrays.fill(elementData, null);
    size = 0;
  }

  public String toString() {
    if (size == 0) {
      return "[]";
    } else {
      StringBuilder sb = new StringBuilder("[");
      for (int i = size - 1; i > -1; i--) {
        sb.append(elementData[i].toString() + ", ");
      }
      int len = sb.length();
      return sb.delete(len - 2, len).append("]").toString();
    }
  }
}

 顺序栈实现2

package lang;

import java.util.ArrayList;
import java.util.EmptyStackException;

public class ArrayStack2<E> extends ArrayList<E> {

  /**
   * @Fields serialVersionUID : TODO
   */
  private static final long serialVersionUID = -4396620094929287983L;

  public ArrayStack2() {
    super();
  }

  public ArrayStack2(final int initialSize) {
    super(initialSize);
  }

  public boolean empty() {
    return isEmpty();
  }

  public E peek() throws EmptyStackException {
    final int n = size();
    if (n <= 0) {
      throw new EmptyStackException();
    } else {
      return get(n - 1);
    }
  }

  public E peek(final int n) throws EmptyStackException {
    final int m = (size() - n) - 1;
    if (m < 0) {
      throw new EmptyStackException();
    } else {
      return get(m);
    }
  }

  public E pop() throws EmptyStackException {
    final int n = size();
    if (n <= 0) {
      throw new EmptyStackException();
    } else {
      return remove(n - 1);
    }
  }

  public E push(final E item) {
    add(item);
    return item;
  }

  public int search(final Object object) {
    int i = size() - 1; // Current index
    int n = 1; // Current distance
    while (i >= 0) {
      final Object current = get(i);
      if ((object == null && current == null)
        || (object != null && object.equals(current))) {
        return n;
      }
      i--;
      n++;
    }
    return -1;
  }
}


2. 链式栈的实现:

package lang;

import java.io.Serializable;

/**
 * @ClassName: LinkStack
 * @Description: 链式栈
 * @date 2014年1月20日 下午3:46:40
 * @param <T>
 */
public class LinkStack<T> implements Serializable{
  /**
   * @Fields serialVersionUID : TODO
   */
  private static final long serialVersionUID = -4378447264374701299L;

  private class Node{
    private T data; //保存节点的数据 
    
    private Node next; //指向下个节点的引用
    
    public Node(){
      
    }
    
    public Node(T data, Node next){
      this.data = data;
      this.next = next;
    }
  }
  
  private Node top;  //保存该链栈的栈顶元素   
 
  private int size = 0;   //保存该链栈中已包含的节点数,即栈的长度

  public LinkStack(){
    top = null;
  }
  
  public LinkStack(T element) {
    top = new Node(element , null);   
    size++; 
  }
  
  /**
   * @Title: size     
   * @Description: 栈的长度    
   * @return
   */
  public int size(){
    return size;
  }
  
  /**
   * @Title: push     
   * @Description: 入栈    
   * @param element
   */
  public void push(T element){
    top = new Node(element , top);   
    size++;
  }
  
  /**
   * @Title: pop     
   * @Description: 出栈    
   * @return
   */
  public T pop(){
    Node oldTop = top;
    top = top.next;
    oldTop.next = null;
    size--;
    return oldTop.data;
  }
  
  /**
   * @Title: peek     
   * @Description: 访问栈顶元素    
   * @return
   */
  public T peek(){
    return top.data;
  }
  
  /**
   * @Title: empty     
   * @Description: 判断顺序栈是否为空栈    
   * @return
   */
  public boolean isEmpty() {
    return size == 0;
  }

  /**
   * @Title: clear     
   * @Description: 清空顺序栈
   */
  public void clear() {   
    top = null;//将栈所有元素赋为null
    size = 0;
  }

  public String toString() {   
        //链栈为空链栈时   
    if (isEmpty()) {   
      return "[]";   
    } else {   
      StringBuilder sb = new StringBuilder("[");   
      for (Node current = top ; current != null ; current = current.next ) {   
        sb.append(current.data.toString() + ", ");   
      }   
      int len = sb.length();   
      return sb.delete(len - 2 , len).append("]").toString();   
    }   
  }   

}

 

3. 栈的应用

3.1 将10进制正整数num转换为n进制

package stack.apply;

import org.junit.Test;

import lang.ArrayStack;

/**
 * @ClassName: Conversion
 * @Description: 将10进制正整数num转换为n进制
 * @date 2014年1月21日 上午9:47:22
 */
public class Conversion {
  
  /**
   * @Title: conversion     
   * @Description: 将10进制正整数num转换为n进制    
   * @param num: 10进制正整数
   * @param n: n进制
   * @return 转换后的值
   */
  private String conversion(int num, int n) {
    ArrayStack<Integer> myStack = new ArrayStack<Integer>();
    Integer result = num;
    while (true) {
      // 将余数入栈
      myStack.push(result % n);
      result = result / n;
      if (result == 0) {
        break;
      }
    }
    StringBuilder sb = new StringBuilder();
    // 按出栈的顺序倒序排列即可
    while ((result = myStack.pop()) != null) {
      sb.append(result);
    }
    return sb.toString();
  }
  
  @Test
  public void testConversion(){
    String s = conversion(13,2);
    System.out.println(s);
  }
}


3.2 行编辑:

输入行中字符'#'表示退格, '@'表示之前的输入全都无效.

package stack.apply;

import org.junit.Test;

import lang.ArrayStack;

/**
 * @ClassName: LineEdit
 * @Description: 行编辑: 输入行中字符'#'表示退格, '@'表示之前的输入全都无效.
 * @date 2014年1月21日 上午10:17:06
 */
public class LineEdit {
  /**
   * @Title: lineEdit     
   * @Description: 行编辑    
   * @param input
   * @return
   */
  private String lineEdit(String input) {
    ArrayStack<Character> myStack = new ArrayStack<Character>();
    char[] arr = input.toCharArray();
    for (char c : arr) {
      if (c == '#') {
        myStack.pop();
      } else if (c == '@') {
        myStack.clear();
      } else {
        myStack.push(c);
      }
    }
    
    StringBuilder sb = new StringBuilder();
    Character temp = null;
    while ((temp = myStack.pop()) != null) {
      sb.append(temp);
    }
    // 反转字符串
    sb.reverse();
    return sb.toString();
  }
  
  @Test
  public void testLineEdit(){
    String s = lineEdit("abcd#dsa@#usera#22#8");
    System.out.println(s);
  }
}


3.3 检验符号是否匹配.

 '['和']', '('和')'成对出现时字符串合法. 
   例如"[][]()", "[[([]([])()[])]]"是合法的; "([(])", "[())"是不合法的

package stack.apply;

import org.junit.Test;

import lang.ArrayStack;

/**
 * @ClassName: Match
 * @Description: 检验符号是否匹配. '['和']', '('和')'成对出现时字符串合法. 
 * 例如"[][]()", "[[([]([])()[])]]"是合法的; "([(])", "[())"是不合法的
 * @date 2014年1月21日 上午10:14:47
 */
public class Match {
  /**
   * @Title: isMatch     
   * @Description: 检验符号是否匹配    
   * @param str 输入要匹配的字符串
   * @return 是否匹配
   */
  public boolean isMatch(String str) {
    ArrayStack<Character> myStack = new ArrayStack<Character>();
    char[] arr = str.toCharArray();
    for (char c : arr) {
      Character temp = myStack.pop();
      // 栈为空时只将c入栈
      if (temp == null) {
        myStack.push(c);
      }
      // 配对时c不入栈
      else if (temp == '[' && c == ']') {
      } 
      // 配对时c不入栈
      else if (temp == '(' && c == ')') {
      } 
      // 不配对时c入栈
      else {
        myStack.push(temp);
        myStack.push(c);
      }
    }
    return myStack.isEmpty();
  }
  
  @Test
  public void testMatch(){
    boolean b = isMatch("[[([]([])()[])]]");
    System.out.println(b);
  }
}
  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值