目录
栈
代码实现
import java.util.Iterator;
public class Stack<T> implements Iterable <T>{
//记录首结点
private Node head;
//记录栈中的元素个数
private int N;
private class Node{
public T item;
public Node next;
public Node(T item,Node next)
{
this.item=item;
this.next=next;
}
}
public Stack() {
this.head=new Node(null,null);
this.N=0;
}
//判断当前栈中的元素个数是否为0
public boolean isEmpty()
{
return N==0;
}
//获取栈中元素个数
public int size()
{
return N;
}
//将元素压入栈,与链表中插入结点的处理几乎一样,只不过一只从头结点插入
public void push(T t)
{
//找到首结点指向的第一个结点
Node oldFirst=head.next;
//创建新结点
Node newNode =new Node(t,null);
//让首结点指向新结点
head.next=newNode;
//让新结点指向原来的第一个结点
newNode.next=oldFirst;
N++;//压入了元素,元素肯定变多啦
}
//弹出元素,其实就是首结点越过第一个结点,与第二个结点相连(指向原来第一个结点的下一个结点)
public T pop()
{
//找到首结点指向的第一个结点
Node oldFirst=head.next;//可能是空的链表,所以要安全处理一下下
if(oldFirst==null)
{
return null;
}
//让首结点指向原来第一个结点的下一个结点
head.next=oldFirst.next;
//弹出元素,肯定元素个数变少了
N--;
return oldFirst.item;
}
public Iterator<T> iterator()
{
return new Literator();
}
private class Literator implements Iterator{
private Node n;
public Literator()
{
this.n=head;
}
public boolean hasNext()
{
return n.next!=null;
}
public Object next()
{
n=n.next;
return n.item;
}
}
}
public class test {
public static void main(String[] args)
{
//创建栈对象
Stack<String>stack=new Stack<>();
//测试压栈
stack.push("a");
stack.push("b");
stack.push("c");
stack.push("d");
for(String i:stack)
{
System.out.println(i);
}
System.out.println("————————————————————————————————————————————————");
//测试弹栈
String result=stack.pop();
System.out.println("弹出的元素是"+result);
System.out.println("剩余的元素的个数是:"+stack.size());
}
}
括号匹配问题
代码实现
public class test {
public static void main(String[] args)
{
String str="(小无(小北)())";
boolean isf=isf(str);
System.out.println(str+"中的括号是否匹配:"+isf);
}
public static boolean isf(String str)
{
//创建栈对象,存储左括号
Stack<String> chars=new Stack<>();
//从左往右遍历字符串
for(int i=0;i<str.length();i++)
{
//字符型的话返回不方便,定义成字符串型
String currchar=str.charAt(i)+"";
//判断是否为左括号,如果是,压入栈
if(currchar.equals("("))
{
chars.push(currchar);
}
else if(currchar.equals(")"))
{//判断是否是右括号,如果是,从栈中弹出元素(左括号)
String p= chars.pop();
if(p==null)
{
return false;
}
}
}
//上面的遍历已经把所有右括号对应是否有左括号并进行操作处理完毕
//最后我们检查栈中是否还有左括号即可
if(chars.size()==0)
{
return true;
}
else
{
return false;
}
}
}
import java.util.Iterator;
public class Stack<T> implements Iterable <T>{
//记录首结点
private Node head;
//记录栈中的元素个数
private int N;
private class Node{
public T item;
public Node next;
public Node(T item,Node next)
{
this.item=item;
this.next=next;
}
}
public Stack() {
this.head=new Node(null,null);
this.N=0;
}
//判断当前栈中的元素个数是否为0
public boolean isEmpty()
{
return N==0;
}
//获取栈中元素个数
public int size()
{
return N;
}
//将元素压入栈,与链表中插入结点的处理几乎一样,只不过一只从头结点插入
public void push(T t)
{
//找到首结点指向的第一个结点
Node oldFirst=head.next;
//创建新结点
Node newNode =new Node(t,null);
//让首结点指向新结点
head.next=newNode;
//让新结点指向原来的第一个结点
newNode.next=oldFirst;
N++;//压入了元素,元素肯定变多啦
}
//弹出元素,其实就是首结点越过第一个结点,与第二个结点相连(指向原来第一个结点的下一个结点)
public T pop()
{
//找到首结点指向的第一个结点
Node oldFirst=head.next;//可能是空的链表,所以要安全处理一下下
if(oldFirst==null)
{
return null;
}
//让首结点指向原来第一个结点的下一个结点
head.next=oldFirst.next;
//弹出元素,肯定元素个数变少了
N--;
return oldFirst.item;
}
public Iterator<T> iterator()
{
return new Literator();
}
private class Literator implements Iterator{
private Node n;
public Literator()
{
this.n=head;
}
public boolean hasNext()
{
return n.next!=null;
}
public Object next()
{
n=n.next;
return n.item;
}
}
}
逆波兰表达式求值问题
代码实现
public class test {
public static void main(String[] args)
{
//4*(20-18)+9/3的波兰表达式如下
String[] notation= {"4","20","18","-","*","9","3","/","+"};
int result =caculate(notation);
System.out.println("逆波兰表达式的计算结果为:"+result);
}
public static int caculate(String[] notation)
{
//定义一个栈,存储操作数
Stack<Integer> ap=new Stack<>();
//从左往右遍历逆波兰表达式,判断当前元素是运算符还是操作数、
如果是运算符,从栈中弹出2个操作数
//如果是操作数,将其放入栈中
for(int i =0;i<notation.length;i++)
{
String curr=notation[i];
Integer b1,b2,result;
switch(curr)
{//此时要注意应该是第二个弹出的元素减去(操作)第一个弹出的元素
case"+":
b1=ap.pop();
b2=ap.pop();
result=b2+b1;
ap.push(result);
break;
case"-":
b1=ap.pop();
b2=ap.pop();
result=b2-b1;
ap.push(result);
break;
case"*":
b1=ap.pop();
b2=ap.pop();
result=b2*b1;
ap.push(result);
break;
case"/":
b1=ap.pop();
b2=ap.pop();
result=b2/b1;
ap.push(result);
break;
default:
ap.push(Integer.parseInt(curr));
break;
}
}
//得到栈中的末尾元素,返回结果
int result=ap.pop();
return result;
}
}
import java.util.Iterator;
public class Stack<T> implements Iterable <T>{
//记录首结点
private Node head;
//记录栈中的元素个数
private int N;
private class Node{
public T item;
public Node next;
public Node(T item,Node next)
{
this.item=item;
this.next=next;
}
}
public Stack() {
this.head=new Node(null,null);
this.N=0;
}
//判断当前栈中的元素个数是否为0
public boolean isEmpty()
{
return N==0;
}
//获取栈中元素个数
public int size()
{
return N;
}
//将元素压入栈,与链表中插入结点的处理几乎一样,只不过一只从头结点插入
public void push(T t)
{
//找到首结点指向的第一个结点
Node oldFirst=head.next;
//创建新结点
Node newNode =new Node(t,null);
//让首结点指向新结点
head.next=newNode;
//让新结点指向原来的第一个结点
newNode.next=oldFirst;
N++;//压入了元素,元素肯定变多啦
}
//弹出元素,其实就是首结点越过第一个结点,与第二个结点相连(指向原来第一个结点的下一个结点)
public T pop()
{
//找到首结点指向的第一个结点
Node oldFirst=head.next;//可能是空的链表,所以要安全处理一下下
if(oldFirst==null)
{
return null;
}
//让首结点指向原来第一个结点的下一个结点
head.next=oldFirst.next;
//弹出元素,肯定元素个数变少了
N--;
return oldFirst.item;
}
public Iterator<T> iterator()
{
return new Literator();
}
private class Literator implements Iterator{
private Node n;
public Literator()
{
this.n=head;
}
public boolean hasNext()
{
return n.next!=null;
}
public Object next()
{
n=n.next;
return n.item;
}
}
}