栈_java

栈介绍

概念
栈是一种只允许在一端进行插入或删除的线性表。

  • 栈的操作端通常被称为栈顶,另一端被称为栈底。
  • 栈的插入操作称为进栈(压栈|push);栈删除操作称为出栈(弹栈|pop)。

特点
  栈就像一个杯子,我们只能从杯口放和取,所以栈中的元素是“先进后出”的特点。

存储结构
  顺序存储的栈称为顺序栈;链式存储的栈称为链式栈。
  
我们可以围绕栈的4个元素来实现栈:

  • 2状态:是否栈空;是否栈满。

  • 2操作:压栈push;进栈pop。

顺序栈

在这里插入图片描述
 
具体实现

package.数组实现顺序栈;
/**
 * 
 * @author JHL
 *顺序栈(SqStack)一般用数组来实现,主要有四个元素:2状态2操作。
 * 2状态:栈空?;栈满?
 * 2操作:压栈push;弹栈pop。
 * @param <T>
 */

public class SqStack<T>{
	T data[];//用数组表示栈元素
	int maxSize;//栈空间大小(常量)
	int top;//栈顶指针(指向栈顶元素)
	
	public SqStack(int maxSize) {
		this.maxSize=maxSize;
		//泛型数组不能直接new创建,需要使用Object来创建(其实一开始也可以直接使用Object来代替泛型)
		this.data=(T[]) new Object[maxSize];
		//有的书中使用0,但这样会占用一个内存
		this.top=-1;
	}
	
   //判断栈是否为空
	public boolean isNull() {
		boolean flag=this.top<=-1?true:false;
		return flag;
	}
	
	 //判断是否栈满
	public boolean isFull(){
		boolean flag = this.top==this.maxSize-1?true:false;
		return flag;
	}
	 //压栈
	 public boolean push(T vaule){
	    if(isFull()){
	         //栈满
	          return false;
	     }else{
	          data[++top] = vaule;//栈顶指针加1并赋值
	          return true;
	     }
	 }
	
    //弹栈
	 public T pop(){
        if(isNull()){
         //栈为空
	            return null;
        }else{
	          T value = data[top];//取出栈顶元素
	          --top;//栈顶指针-1
	          return value;
	       }
	   }
	 
	 //测试
	 public static void main(String[] args) {
		  //初始化栈(char类型)
	        SqStack<Character> stack = new SqStack<Character>(10);
	        
	        //2状态
	        System.out.println("栈是否为空:"+stack.isNull());
	        System.out.println("栈是否已满:"+stack.isFull());
	        
	        //2操作
	        //依次压栈
	        stack.push('a');
	        stack.push('b');
	        stack.push('c');
	        //依次弹栈
	        System.out.println("弹栈顺序:");
	        System.out.println(stack.pop());
	        System.out.println(stack.pop());
	        System.out.println(stack.pop());
	}
}

链栈

在这里插入图片描述
具体实现

package.链实现栈;

/**
  * @author JHL
  @Description TODO:
  *链栈(LinkStack)用链表来实现,主要有四个元素:2状态2操作。
  * 2状态:栈空?;栈满(逻辑上永远都不会栈满,除非你的电脑没内存了^_^)。
  * 2操作:压栈push;弹栈pop。
  * @param <T>
 */

 class LinkStack<T>{
     //栈顶节点
     private LinkNode<T> top;
     
     //初始化1
     public LinkStack(){
         this.top = new LinkNode<T>();
     }
     
     //初始化栈
     public void initStack(){
         this.top.setData(null);
         this.top.setNext(null);
     }
     //是否栈空
     public boolean isNull(){
         boolean flag = top.getNext()==null?true:false;
         return flag;
     }
     
     //压栈
     public void push(LinkNode<T> node){
         if(isNull()){
             //栈空,即第一次插入
             top.setNext(node);
             node.setNext(null);//该句可以省略(首次插入的元素为栈底元素)
         }else{
             node.setNext(top.getNext());
             top.setNext(node);
         }
     }
     
     //弹栈
     public LinkNode<T> pop(){
         if(isNull()){
           //栈空无法弹栈
             return null;
         }else{
             LinkNode<T> delNode = top.getNext();//取出删除节点
             top.setNext(top.getNext().getNext());//删除节点
             return delNode;
         }
     }
     //测试
     public static void main(String[] args) {
    	 LinkStack<Character> ls = new LinkStack<Character>();
    	          
    	          //1状态
    	          System.out.println("栈是否为空:"+ls.isNull());
    	          
    	          //2操作
    	          //依次压栈
    	          ls.push(new LinkNode<Character>('a'));
    	          ls.push(new LinkNode<Character>('b'));
    	          ls.push(new LinkNode<Character>('c'));
    	          
    	          //依次弹栈
    	          System.out.println("弹栈顺序:");
    	          System.out.println(ls.pop().getData());
    	          System.out.println(ls.pop().getData());
    	          System.out.println(ls.pop().getData());
	}
 }
 
 
//链式栈节点(外部类实现,也可以使用内部类)
 class LinkNode<T>{
     private T data;//数据域
     private LinkNode<T> next;//指针域
     
     //初始化1
     public LinkNode(){
         this.data = null;
         this.next = null;
     }
     
     //初始化2
     public LinkNode(T data) {
         super();
         this.data = data;
         this.next = null;
     }
     public T getData() {
         return data;
     }
     public void setData(T data) {
         this.data = data;
     }
     public LinkNode<T> getNext() {
         return next;
     }
     public void setNext(LinkNode<T> next) {
         this.next = next;
     }
 }

栈的应用

栈结构是很基本的一种数据结构,所以栈的应用也很常见,根据栈结构“先进后出”的特点,我们可以在很多场景中使用栈,下面我们就是使用上面我们已经实现的栈进行一些常见的应用:十进制转N进制、行编辑器、校验括号是否匹配、中缀表达式转后缀表达式、表达式求值等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值