栈的实现及应用学习笔记--Java实现
2017-10-01 16:22
337 查看
1.定义
栈(Stack)是限定仅在表尾进行插入或删除操作的线性表。因此。表尾端有其特殊含义,称为栈顶(top),相应地,表头端称为栈低。一般来说,栈主要有两个操作:一个是进栈(PUSH),另一个是出栈(POP)。2. 栈的表示和实现
1) 顺序栈,即栈的顺序存储结构,利用一组地址连续的存储单元依次存放自栈低到栈顶的数据元素。–java实现
public class ArrayStack<T> implements Serializable { 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]; // 设置栈的长度 } public ArrayStack(T element) { this(); elementData[0] = element; size++; } public ArrayStack(T element, int initSize) { this.capacity = initSize; elementData = new Object[capacity]; elementData[0] = equals(element); size++; } /* * @Description: 栈长度 */ public int size() { return size; } /** * @description:入栈 */ public void push(T element) { // TODO Auto-generated method stub ensureCapacity(size + 1); elementData[size++] = element; } // 如果数组的原有长度小于目前所需的长度 ,进行扩容 private void ensureCapacity(int capacity) { // TODO Auto-generated method stub int oldcapacity = elementData.length; if (capacity > oldcapacity) { int newCapacity = (oldcapacity * 3) / 2 + 1; if (newCapacity < capacity) { newCapacity = capacity; } // minCapacity is usually close to size elementData = Arrays.copyOf(elementData, newCapacity); } } /** * @description: 出栈 */ public T pop() { if (!isEmpty()) { T lastValue = (T) elementData[size - 1]; // 释放栈顶元素 elementData[--size] = null; return lastValue; } else { return null; } } /** * @Description: 返回栈顶元素,但不删除栈顶元素 */ public T peek() { if (!isEmpty()) { return (T) elementData[size - 1]; } else { throw new IndexOutOfBoundsException("空栈异常"); } } public boolean isEmpty() { // TODO Auto-generated method stub return size == 0; } /** * @Description: 清空顺序栈 */ public void clear() { // 将底层数组所有元素赋为null Arrays.fill(elementData, null); size = 0; } public String toString() { if (size == 0) { return "[]"; } else { StringBuilder sbBuilder = new StringBuilder("["); for (int i = size -1 ; i >= 0; i--) { sbBuilder.append(elementData[i].toString() + ","); } int len = sbBuilder.length(); return sbBuilder.delete(len - 1, len).append("]").toString(); } } }
2)栈的链表表示
–java 实现
import java.io.Serializable; public class LinkStack<T> implements Serializable { private static final long serialVersionUID = -4378447264374701299L; private class Node { private T data; // 保存节点的数据 private Node next; public Node() { // TODO Auto-generated constructor stub } public Node(T data, Node next) { this.data = data; this.next = next; } } private Node top; // 保存该链表栈的栈顶元素 private int size = 0; // 保存该链栈中已包含的节点数,即栈的长度 public LinkStack() { // TODO Auto-generated constructor stub top = null; } public LinkStack(T element) { top = new Node(element, null); size++; } /** * @Description: 栈的长度 */ public int size() { return size; } /** * @despriction: 入栈 **/ public void push(T element) { top = new Node(element, top); size++; } /** * @Description: 出栈 **/ public T pop() { Node oldTop = top; top = top.next; oldTop.next = null; size--; return oldTop.data; } /** * @Description: 访问栈顶元素 */ public T peek() { return top.data; } /** * @Description: 判断顺序栈是否为空栈 */ public boolean isEmpty() { return size == 0; } /** * @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. 栈的应用
1) 进制转换通过求余法可以将十进制转换为其他进制,比如要转为8 进制,则将原是进制除以8,记录余数,然后继续将商除以8,一直到商为 0为止,最后将余数倒序写出来即可。
–java实现
public class Conversion { /** * @Title: conversion * @Description: 将10进制正整数num转换为n进制 * @param num: 10进制正整数 * @param n: n进制 * @return 转换后的值 */ public 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 sBuilder = new StringBuilder(); //按栈的 顺序倒序输出即可 while ((result = myStack.pop()) != null) { sBuilder.append(result); } return sBuilder.toString(); } }
2) 括号匹配检验
一般编程语言中括号都是成对出现的,比如:[],(),{}
凡是遇到括号的前半部分,即为入栈符号(PUSH);凡是遇到括号后半部分,就比对是否与栈顶元素相匹配(PEEK),如果相匹配,则出栈(POP),否者就匹配出错。
–Java实现
public class symbol_match { 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 == ')') { } else { myStack.push(temp); myStack.push(c); } } return myStack.isEmpty(); } }
3)行编辑
–java实现
/** * @ClassName: LineEdit * @Description: 行编辑: 输入行中字符'#'表示退格, '@'表示之前的输入全都无效. */ public class lineEdit { public 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 sBuilder = new StringBuilder(); Character temp = null; while((temp = myStack.pop()) != null){ sBuilder.append(temp); } sBuilder.reverse(); return sBuilder.toString(); } }
4)汉诺塔游戏,递归实现
汉诺塔问题的描述如下:有A、B和C 3跟柱子,在A上从下往上按照从小到大的顺序放着 n 个圆盘,以B为中介,把盘子全部移动到C上。移动过程中,要求任意盘子的下面要么没有盘子,要么只能有比它大的盘子。本实例将演示如何求解3阶汉诺塔问题。
思路解析
为了将N个盘子从A移动到C,需要先将第N个盘子上面的N-1个盘子移动到B上,这样才能将第N个盘子移动到C上。同理,为了将第N-1个盘子从B移动到C上,需要将N-2个盘子移动到A上,这样才能将第N-1个盘子移动到C上。通过递归就可以实现汉诺塔问题的求解。
–java实现
import java.io.BufferedReader; import java.io.InputStreamReader; public class hanoi { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub int n; BufferedReader buf = new BufferedReader(new InputStreamReader(System.in)); System.out.println("请输入盘子数:"); n = Integer.parseInt(buf.readLine()); move(n, 'A','B','C'); } private static void move(int n, char a, char b, char c) { // TODO Auto-generated method stub if (n == 1) { System.out.println("盘 " + n + " 由 " + a + " 移至 " + c); }else{ move(n-1, a, c, b); System.out.println("盘 " + n + " 由 " + a + " 移至 " + c); move(n-1, b, a, c); } } }
运行输出
请输入盘子数: 3 盘 1 由 A 移至 C 盘 2 由 A 移至 B 盘 1 由 C 移至 B 盘 3 由 A 移至 C 盘 1 由 B 移至 A 盘 2 由 B 移至 C 盘 1 由 A 移至 C
相关文章推荐
- Android(java)学习笔记181:Android 服务的应用,在Activity中实现背景音乐播放
- JAVA学习笔记38——模拟实现Iterator+HashMap的“分拣”原理+“分拣”的应用
- Java学习笔记——应用矢量和迭代器来实现类似链表的功能
- Java 死锁的实现 -Java学习笔记(28)
- 用JS实现移动的窗口 - 流星絮语 JAVA学习笔记 - CSDNBlog
- java学习笔记:【从网络获取图像资源】实现
- Java 线程同步问题 生产者-消费者 算法实现 -Java学习笔记(29)
- Java IO 实现文件复制 -Java 学习笔记 (25)
- Java基础学习笔记(七)Set接口及其实现子类
- Java容器学习笔记(二) Set接口及其实现类的相关知识总结
- Servlet学习笔记(一)javaWeb应用基本
- Java学习笔记(三)Map接口及其重要实现类的用法
- 【学习笔记】Thinking in java (第三版)第五章 隐藏实现(Hiding the implementation)
- Java基础学习笔记(七)Set接口及其实现子类
- 《(学习笔记)两天进步一点点》(3)——应用BindingSource实现数据同步
- 电信增值业务学习笔记9——基于智能网的增值业务实现技术和应用
- Java 实现 文件目录 遍历 - Java 学习笔记 (22)
- 设计模式学习笔记以及java代码实现
- java(j2se)学习笔记----如何实现四舍五入?
- Java学习笔记---8.面向对象编程03-String类的重点应用