栈的实现及应用学习笔记--Java实现
来源:互联网 发布:西安交大远程网络教育 编辑:程序博客网 时间:2024/06/06 07:02
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
阅读全文
0 0
- 栈的实现及应用学习笔记--Java实现
- 栈的实现及应用
- 栈的实现及应用
- java实现队列及队列的应用
- 观察者模式的Java实现及应用
- 观察者模式的Java实现及应用
- Android学习笔记_35_PopupWindow泡泡窗口的实现及GridView应用
- 堆栈java实现及应用
- java学习:ArrayList的实现及原理
- JAVA学习笔记38——模拟实现Iterator+HashMap的“分拣”原理+“分拣”的应用
- Java学习笔记——应用矢量和迭代器来实现类似链表的功能
- java学习笔记----回调的实现
- 栈(Stack)的python实现及应用
- Ioc的实现及应用
- Ioc的实现及应用
- 遮罩层的实现及应用
- CocurrentHashMap的应用及实现
- 神经网络学习笔记3:BP神经网络的实现及其应用
- 【BZOJ2729】【HNOI2012】排队(组合数学)
- git基础指令
- HDU 5556 Land of Farms(枚举+二分图匹配)
- leetcode---combination-sum---dfs
- K:注解处理
- 栈的实现及应用学习笔记--Java实现
- 通过Exiv2读取照片的Exif信息获取GPS,焦距等信息
- seaborn单变量、多变量及回归分析绘图
- PAT 甲级 1057. Stack (30)
- iPhone8可以无线充电吗?绿联无线充电器充电功率实测
- php mysql 获得表记录的总数及获取指定数量的数据
- 创建Hibernate获取Session的工具类
- 乒乓球:浅析业余高手从输球中总结的10条心得!
- 简单选择排序