链式堆栈
链式存储结构的堆栈称作
链式堆栈。
与单链表相同,链式堆栈也是由一个个结点组成的,每个结点由两个域组成,一个是存放数据元素的数据元素域element,另一个是存放指向下一个结点的对象引用(即指针)域next。
堆栈有两端,插入数据元素和删除数据元素的一端为栈顶,另一端为栈底。链式堆栈都设计成把靠近堆栈头head的一端定义为栈顶。
依次向链式堆栈入栈数据元素
a
0
, a
1
, a
2
, ..., a
n-1
后,链式堆栈的示意图如图所示。
//节点类
public class Node {
Object element; // 数据域
Node next; // 指针域
//头结点的构造方法
public Node(Node nextval){
this.next=nextval;
}
//非头结点的构造方法
public Node(Object obj,Node nextval){
this.element=obj;
this.next=nextval;
}
public Object getElement() {
return element;
}
public void setElement(Object element) {
this.element = element;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public String toString()
{
return this.element.toString();
}
}
public interface Stack {
// 入栈
public void push(Object obj) throws Exception;
// 出栈
public Object pop() throws Exception;
// 获得栈顶元素
public Object getTop() throws Exception;
// 判断栈是否为空
public boolean isEmpty();
}
public class LinkedStack implements Stack {
Node head; //栈顶指针
int size; //结点的个数
public LinkedStack(){
this.head=null;
this.size=0;
}
@Override
public void push(Object obj) throws Exception {
// TODO Auto-generated method stub
this.head=new Node(obj,this.head);
this.size++;
}
@Override
public Object pop() throws Exception {
// TODO Auto-generated method stub
if(this.isEmpty()){
throw new Exception("栈为空!");
}
Object obj=this.head.getElement();
this.head=this.head.next;
return obj;
}
@Override
public Object getTop() throws Exception {
// TODO Auto-generated method stub
return this.head.getElement();
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return this.head==null;
}
}
import java.util.Scanner;
public class LinkedStackTest {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Stack stack=new LinkedStack();
Scanner in = new Scanner(System.in);
int temp;
for(int i=0;i<10;i++)
{
System.out.println("请输入第"+(i+1)+"个整数:");
temp = in.nextInt();
stack.push(temp);
}
while(!stack.isEmpty())
{
System.out.println(stack.pop());
}
}
}
测试结果:输入的是10,9,8,7,6,5,4,3,2,1
输出的是:1,2,3,4,5,6,7,8,9,10
堆栈的应用
括号匹配问题
假设算术表达式中包含圆括号,方括号,和花括号三种类型。使用栈数据结构编写一个算法判断表达式中括号是否正确匹配,并设计一个主函数测试。
比如:{a+[b+(c*a)/(d-e)]} 正确
([a+b)-(c*e)]+{a+b} 错误
public class Test {
public static String[] expToStringArray(String exp)
{
int n = exp.length();
String[] arr = new String[n];
for(int i=0;i<arr.length;i++)
{
arr[i]= exp.substring(i, i+1);
}
return arr;
}
public static void signCheck(String exp)throws Exception
{
SequenceStack stack = new SequenceStack();
String[] arr = Test.expToStringArray(exp);
for(int i=0;i<arr.length;i++)
{
if(arr[i].equals("(")||arr[i].equals("[")||arr[i].equals("{"))
{
stack.push(arr[i]);
}
else if(arr[i].equals(")")&& !stack.isEmpty()&& stack.getTop().equals("("))
{
stack.pop();
}
else if(arr[i].equals(")")&& !stack.isEmpty()&& !stack.getTop().equals("("))
{
System.out.println("左右括号匹配次序不正确!");
return ;
}
else if(arr[i].equals("]")&& !stack.isEmpty()&& stack.getTop().equals("["))
{
stack.pop();
}
else if(arr[i].equals("]")&& !stack.isEmpty()&& !stack.getTop().equals("["))
{
System.out.println("左右括号匹配次序不正确!");
return ;
}
else if(arr[i].equals("}")&& !stack.isEmpty()&& stack.getTop().equals("{"))
{
stack.pop();
}
else if(arr[i].equals("}")&& !stack.isEmpty()&& !stack.getTop().equals("{"))
{
System.out.println("左右括号匹配次序不正确!");
return ;
}
else if(arr[i].equals(")")||arr[i].equals("]")||arr[i].equals("}")&& stack.isEmpty())
{
System.out.println("右括号多于左括号!");
return ;
}
}
if(!stack.isEmpty())
{
System.out.println("左括号多于右括号!");
}
else
{
System.out.println("括号匹配正确!");
}
}
public static void main(String[] args) throws Exception {
String str = "([(a+b)-(c*e)]+{a+b}";
Test.signCheck(str);
}
}