栈和队列

栈和队列不适合作为数据的记录工具,它们更多地是作为程序员的工具来运用。主要作为构思算法的辅助工具,而不是完全的数据存储工具。这些数据结构的生命周期比数组、链表等数据库类型的结构要短的多。在程序操作执行期间他们才被创建,通常用它们去执行某项特殊的任务;当完成任务后,它们就被销毁。

       下面的StackX类,实现一个栈的功能:

package com.js.ai.modules.pointwall.testxfz;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 
 * @ClassName: StackX
 * @Description: 堆栈类
 * @author: xfzhong
 * @date: 2017年5月24日 
 */
class StackX{
	private int maxSize;
	private char[] stackArray;
	private int top;
	/**
	 * 
	 * @Title:StackX
	 * @Description:StackX是构造方法,根据参数规定的容量创建一个新栈。
	 * 栈的域包括表示最大容量的变量、数组本身以及变量top,它存储栈顶元素的下标。
	 * @param max
	 */
	public StackX(int max) {
		maxSize=max;
		stackArray=new char[maxSize];
		top=-1;
	}
	/**
	 * 
	 * @Title: push
	 * @Description: Push(入栈)方法中将top值增加一,
	 * 使它指向原顶端数据项的上面的一个位置,
	 * 并在在这个位置上存储一个数据项,
	 * 再次提醒,top是在插入数据项之前递增的。
	 * 入栈,注意要先将top指针上移,然后将数据赋值给新的top位置
	 * @param j
	
	 * @return: void
	 */
	public void push(char j){
		stackArray[++top]=j;
	}
	/**
	 * 
	 * @Title: pop
	 * @Description: Pop方法返回top标识的数据项值,然后top减一。
	 * 这个方法有效地从栈中移除了数据项;虽然数据项仍然存在数组中,
	 * 直到有新的数据项压入栈中覆盖这个数据项。但是它不能再被访问了。
	 * 出栈,先取得数据,然后将top下移
	 * @return
	
	 * @return: char
	 */
	public char pop(){
		return stackArray[top--];
	}
	/**
	 * 
	 * @Title: peek
	 * @Description: Peek方法仅返回top所指的数据项的值,不对栈做任何改动。
		只查看栈顶的元素,top指针不动。
	 * @return
	
	 * @return: char
	 */
	public char peek(){
		return stackArray[top];
	}
	/**
	 * 
	 * @Title: isEmpty
	 * @Description: IsEmpty方法在栈空时返回true,栈空时top值为-1。
	 * @return
	
	 * @return: boolean
	 */
	public boolean isEmpty(){
		return (top==-1);
	}
 }
/**
 * 
 * @ClassName: BracketChecker
 * @Description: 分隔符匹配(检查)
 * 一种典型的应用是栈用于解析某种类型的文本串。通常,文本串是计算机语言写的代码行,
 * 而解析它们的程序就是编译器。一个典型的例子是分隔符匹配程序,它从字符串中不断读取字符,
 * 每次读取一个字符。若发现它是一个左分隔符,将它压入栈中。当从输入中读到一个右分隔符时,
 * 弹出栈顶的左分隔符,并且查看它是否合右分隔符相匹配。如果它们不匹配,则程序报错。
 * 如果栈中没有左分隔符和右分隔符匹配,或者一直存在着没有被匹配的分隔符,程序也报错。
 * 这个方法的可行性在于,最后出现的左边分隔符需要最先匹配,这个规律符合栈的后进先出的特点。
下面是分隔符匹配程序的代码:
 * @author: xfzhong
 * @date: 2017年5月24日 
 */
class BracketChecker{
	private String input;
	public BracketChecker(String in) {
		input=in;
	}
	public void check(){
		int stackSize=input.length();
		StackX theStack=new StackX(stackSize);
		for(int j=0;j<input.length();j++){
			char ch=input.charAt(j);
			switch (ch) {
			case '{':
			case '[':
			case '(':
		    theStack.push(ch);
		    break;
		    
			case '}':
			case ']':
			case ')':
		   if(!theStack.isEmpty()){
			   char chx=theStack.pop();
			   if((ch=='}' && chx!='{')||(ch==']' && chx!='[')||(ch==')' && chx!='(')){
				   System.out.println("error:"+ch+"at"+j);
			   }			
		   }
		   else {
			   System.out.println("error:"+ch+"at"+j);
		}
		    break;
			default:
				break;
			}
		}
		if(!theStack.isEmpty())
			System.out.println("error:missing right delimiter!");
	}
}
/**
 * 
 * @ClassName: BracketsApp
 * @Description: 括号类BracketsApp
 * @author: xfzhong
 * @date: 2017年5月24日 
 */
class BracketsApp{
	public static String getString() throws IOException{
		InputStreamReader isr=new InputStreamReader(System.in);
		BufferedReader br=new BufferedReader(isr);
		String s=br.readLine();
		return s;
	}
	public static void main(String[] args) throws IOException {
		String input;
		while(true){
			System.out.println("error:string containing delimiter!");
			System.out.flush();
			input=getString();
			if(input.equals(""))
				break;
			BracketChecker theChecker=new BracketChecker(input);
			theChecker.check();
		}
	}
}
/**
 * 
 * @ClassName: Queue
 * @Description: 队列实现代码
 * @author: xfzhong
 * @date: 2017年5月24日 
 */
class Queue{
	private int maxSize;
	private long[] queArray;
	private int front;
	private int rear;
	private int nItems;
	public Queue(int s) {
		maxSize=s;
		queArray=new long[maxSize];
		front=0;
		rear=-1;
		nItems=0;
	}
	/**
	 * 
	 * @Title: insert
	 * @Description: insert()方法:运行的前提条件是队列未满,
	 * 若插入已满队列时,会抛出异常。若可以插入,则是将rear(队尾指针)加一后,
	 * 在队尾指针所指的位置处插入新的数据项。但是当rear指针指向数组的顶端,
	 * 即maxSize-1位置的时候,在插入数据之前,它必须回绕到数组的底端。
	 * 回绕操作把rear设置为-1,
	 * 因此当rear加1后,它等于0,是数组底端的下标值。最后年Items加1。
	 * @param j
	 * @throws Exception
	
	 * @return: void
	 */
	public void insert(long j) throws Exception{
		if(this.isFull())
		throw new Exception("can not insert because queue is full!");	
		if(rear==maxSize)//deal with wraparound
			rear=-1;
		queArray[++rear]=j;//increment rear and insert增量后插
		nItems++;//one more item
	}
	/**
	 * 
	 * @Title: remove
	 * @Description: remove()方法:前提是队列不空,若对空队列执行此操作时,
	 * 会抛出异常提示。若不空,由front指针得到队头数据项的值,
	 * 然后将front加1。但是如果这样做是front的值超过数组的顶端,
	 * front就必须绕回到数组下标为0的位置上。
	 * 作这个检验之前,先将返回值临时村到,最后年Items减1。
	 * @return
	 * @throws Exception
	
	 * @return: long
	 */
	public long remove() throws Exception{
		if(this.isEmpty())
			throw new Exception("can not remove because queue is empty!");
			long temp=queArray[front++];
			if(front==maxSize)
				front=0;
			nItems--;
			return temp;
	}
	public boolean isFull(){
		return (nItems==maxSize);
	}
	public boolean isEmpty(){
		return (nItems==0);
	}
	public int size(){
		return nItems;
	}
	/**
	 * 
	 * @Title: peekFront
	 * @Description: peek()方法:返回front指针所指数据项的值。isFull()、
	 * isEmpty()、size()都依赖于nItems字段。
	 * @return
	
	 * @return: long
	 */
	public long peekFront(){
		return queArray[front];
	}
	public static void main(String[] args) {
		Queue theQueue=new Queue(5);
		try {
			theQueue.insert(10);
			theQueue.insert(20);
			theQueue.insert(30);
			theQueue.insert(40);
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			theQueue.remove();
			theQueue.remove();
			theQueue.remove();
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			theQueue.insert(50);
			theQueue.insert(60);
			theQueue.insert(70);
			theQueue.insert(80);
		} catch (Exception e) {
			e.printStackTrace();
		}
		while(!theQueue.isEmpty()){
			long n=0;
			try {
				n=theQueue.remove();
			} catch (Exception e) {
				e.printStackTrace();
			}
			System.out.println("n="+n);
			System.out.println(" ");
		}
		System.out.println("");
	}
}
public class TestClass {

}

  优先级队列是比栈和队列更专用的数据结构。它也有队头和队尾指针,也是从队头移除数据项。不过在优先级队列中,数据项按关键字的值有序,这样关键字最小的数据项总是在队头。数据插入的时候会按照顺序插入到合适的位置以确保队列的有序性。下面给出一种使用简单的数组实现优先级队列。这种实现方法插入比较慢,但是它比较简单,适用于数据量比较小,并且不是很注重插入速度的情况。代码如下:

 

posted @ 2017-05-25 18:07  ATJAVA  阅读(201)  评论(0编辑  收藏  举报