《Java数据结构和算法》之栈、队列(学习笔记)

一、栈

     1、定义

          栈是一种只能在表的一端(栈顶)操作的线性表结构,可以基于数组链表实现。

         

    2、特点

           (1)只能访问栈顶元素(最后一个插入的数据项)。栈顶元素被移除出后(或称弹栈),才能访问倒数第二个数据项。

           (2)访问结点必须遵循先进后出后进先出原则。

 

    3、用途介绍

          基于栈后进先出的特点,我们可以用栈来实现字符串反转、匹配符验证(代码实现见5)以及表达式求值(计算器)等等。

 

     4、Java代码实现( 基于数组):

/**
 * 栈
 * 时间复杂度:O(1)
 * @author honyer
 *
 */
public class DefStack {

	 private Object[] stackArray; //存储栈元素的数组
	 private int maxSize;  //栈的容量
	 private int top; //指向栈顶
	 
	 /**
	  * 初始化栈
	  */
	 public DefStack(int size) {
		 this.maxSize = size;
		 this.stackArray = new Object[size];
		 this.top = -1;
	 }
	 
	 /**
	  * 入栈
	  * @param obj
	  * @return true 入栈成功, false 入栈失败
	  */
	 public boolean push(Object obj) {
		 if(isFull()) {
			 return false;
		 }
		 stackArray[++top] = obj;
		 return true;
	 }
	 
	 /**
	  * 弹出栈顶元素(会删除栈顶元素)
	  * @return 返回栈顶元素,top到达栈底之后返回 null元素
	  */
	public Object pop() {
		if(top < 0) {
			return null;
		}
		return  stackArray[top--];
	} 
	 
	 /**
	  * 弹出栈顶元素(不会删除栈顶元素)
	  * @return 返回栈顶元素,top到达栈底之后返回 null元素
	  */
	public Object peek() {
		if(top < 0) {
			return null;
		}
		return  stackArray[top];
	} 
	
	/**
	 * 判断栈是否为空
	 * @return
	 */
	public boolean isEmpty() {
		return top == -1;
	}
	/**
	 * 判断栈是否已满
	 * @return
	 */
	public boolean isFull() {
		return top == maxSize - 1;
	}

}

  PS: 后期会补上链表的实现方式。

 

5、校验大、中、小括号匹配的代码实现:

      

public class BracketChecker {

	private String input;
	
	public BracketChecker(String input) {
		this.input = input;
	}
	
	public boolean check() {
		DefStack expressStack = new DefStack(input.length());
		for(int i = 0; i < input.length(); i++) {
			char ch = input.charAt(i);
			switch(ch) {
				case '{':
				case '[':
				case '(':
					expressStack.push(ch);
					break;
				case '}':
					if('{' != ((char)expressStack.pop())) {
						System.err.println("Error: char at " + i + " must be '}'");
						return false;
					}
					break;
				case ']':
					if('[' != ((char)expressStack.pop())) {
						System.err.println("Error: char at " + i + " must be ']'");
						return false;
					}
					break;
				case ')':
					if('(' != ((char)expressStack.pop())) {
						System.err.println("Error: char at " + i + " must be ')'");
						return false;
					}
					break;
				default:
					break;
			}
		}
		if(!expressStack.isEmpty()) {
			System.err.println("Error: missing rigth delimiter !");
			return false;
		}
		return true;
	}
	
	
	public static void main(String[] args) {
		String input = "{{({} ";
		BracketChecker bc = new BracketChecker(input);
		bc.check();
	}
	
}

   运行结果:               

Error: missing rigth delimiter !

 

二、队列

      1、定义

           一种只能在队尾插入元素和在队头删除元素的线性表,可以基于数组链表实现。它和栈有点类似,不同是队列只能从尾部插入元素。

    2、特点

           (1)头删尾插

           (2)访问结点必须遵循先进先出原则。

 

    3、分类

          基于功能我们可以实现单端队列双端队列阻塞队列以及优先级队列等等

 

     4、Java代码实现( 基于数组):

        

/**
 * 队列(非双端)
 * 时间复杂度:O(1)
 * 采用数组实现,并采用环绕式方式存储元素
 *(即队尾指针到达数组索引length-1的位置后,开始从索引0的位置插入)
 */
public class DefQueue {

	private Object[] queueArray;//实现queue的数组
	private int maxSize; //队列的最大空间
	private int head; //队头
	private int count; //队列中元素的个数
	private int tail; //队尾
	
	public DefQueue(int size) {
		this.maxSize = size;
		this.queueArray = new Object[size];
		this.head = 0;
		this.count = 0;
		this.tail = -1;
	}
	
	/**
	 * 入队
	 * 如果队尾指针已经指向数组最大索引位置,则开始从索引0的位置插入元素(即环绕式插入元素)。 
	 * @param obj
	 * @throws IndexOutOfBoundsException 当队列已满,插入元素会抛出异常 
	 */
	public void add (Object obj) throws IndexOutOfBoundsException{
		if(count == maxSize) {
			throw new IndexOutOfBoundsException("队列已满!");
		}
		if(tail == maxSize -1) {
			tail = -1;
		}
		queueArray[++tail] = obj;
		count++;
	}
	
	/**
	 * 删除
	 * 队列的删除是操作队列头部
	 * @return 队列头部元素
	 */
	public Object remove() {
		if(count == 0) {
			return null;
		}
		Object obj = queueArray[head++];
		if(head >= maxSize) {
			head = 0;
		}
		count--; 
		return obj;
	}
	
	/**
	 * 获取队列头部元素但不删除该元素
	 * @return
	 */
	public Object peekHead() {
		return queueArray[head];
	}
	
	/**
	 * 获取队列尾部元素但不删除该元素
	 * @return
	 */
	public Object peekTail() {
		return queueArray[tail];
	}
	
	/**
	 * 判断队列是否为空
	 * @return
	 */
	public boolean isEmpty() {
		return count == 0;
	}
	
	/**
	 * 判断队列是否已满
	 * @return
	 */
	public boolean isFull() {
		return count == maxSize;
	}
	
	/**
	 * 获取队列中的元素的个数
	 * @return
	 */
	public int size() {
		return count;
	}

}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值