zoukankan      html  css  js  c++  java
  • 栈和队列

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

           下面的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 {
    
    }
    

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

  • 相关阅读:
    移动互联网全新体验Andoid
    《XNA高级编程:Xbox 360和Windows》51
    《XNA高级编程:Xbox 360和Windows》47
    让FCKeditor支持多用户环境(asp.net)
    《XNA高级编程:Xbox 360和Windows》45
    《XNA高级编程:Xbox 360和Windows》46
    《XNA高级编程:Xbox 360和Windows》44
    《XNA高级编程:Xbox 360和Windows》43
    hdu 4314 Save the dwarfs 夜
    poj 3150 Cellular Automaton 夜
  • 原文地址:https://www.cnblogs.com/ipetergo/p/6905280.html
Copyright © 2011-2022 走看看