码迷,mamicode.com
首页 > 其他好文 > 详细

队列

时间:2014-04-30 22:27:39      阅读:318      评论:0      收藏:0      [点我收藏+]

标签:数据结构   java   教学   

生活中,排队随处可见。下面我们就使用java来实现简单的队列吧。

首先,给出接口的定义,也就是规定队列的行为...

package net.itaem.list;

/**
 * 定义一个队列的接口
 * 
 * 队列的定义:FIRST IN FIRST OUT
 * 
 * @author luohong QQ 846705189
 * */
public interface Queue<T> {
    
	/**
	 * 在队尾加入一个元素
	 * */
	public void in(T e);
	
	/**
	 * 从队列头部弹出一个元素,并且删除头部元素
	 * */
	public T out();
	
	/**
	 * 返回队列元素长度
	 * */
	public int size();
	
	/**
	 * 清空一个队列
	 * */
	public void clear();
	
	/**
	 * 获得队列的第一个元素,不删除
	 * */
	public T getFirst();
	
	/**
	 * 获得队列的最后一个元素,不删除
	 * */
	public T getLast(); 
}

下面使用数组来实现一个简单的队列

package net.itaem.list.impl;

import net.itaem.list.Queue;

/**
 * 使用数组来实现一个队列
 * 
 * 这个队列在初始化时就已经确定了队列可以容纳的数量,并且不会动态增长...
 * 
 * @author luohong QQ 846705189
 * 
 * */
public class ArrayQueue<T> implements Queue<T>{

	//队列首部
	private int first;

	//队列尾部的下一个元素
	private int last;
	//定义一个Object[]来保存队列的元素
	private Object[] elements;
	//队列元素的size
	private int size;
	//队列最多能保存的元素个数
	private int length;

	public ArrayQueue(){
		//默认情况下,长度为10
		this(10);
	}
	
	public ArrayQueue(int length){
		if(length < 0) throw new RuntimeException("sorry,不能为负数");
		this.length = length +1;	
		elements = new Object[this.length];
	}


	@Override
	public void in(T e) {
		if(last < length-1){
			size++;
			elements[last++] = e;
		}else{
			throw new RuntimeException("队列已满,不可以继续添加元素");
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public T out() {
		T result = null;

		if(size > 0) {
			result = (T)elements[first];   //这里的first一直都等于0

			for(int i=0; i<size; i++){
				elements[i] = elements[i+1];   //移动后面的算有元素
			}
			//尾部元素移动
            last--;
			//元素长度减去一
			size--;
		}else{
			throw new RuntimeException("队列为空,不能继续弹出元素");
		}

		return result;
	}

	@Override
	public int size() {
		return size;
	}

	@Override
	public void clear() {
		//清空数组的所有应用,防止造成内容溢出
		for(int i=0; i<size; i++){
			elements[i] = null;
		}
		last = 0;
		size = 0;
	}

	@SuppressWarnings("unchecked")
	@Override
	public T getFirst() {
		if(size > 0)
			return (T)elements[0];
		else
			return null;
	}

	@SuppressWarnings("unchecked")
	@Override
	public T getLast() {
		if(size > 0)
			return (T)elements[last-1];
		else 
			return null;
	}

	public String toString(){
		StringBuilder sb = new StringBuilder();
		
		if(size == 0) sb.append("null");
		
		else
			for(int i=0; i<size; i++){
				sb.append(elements[i] + " ");
			}
		return "the queue size is " + size + " and the element is " + sb.toString();
	}

	public static void main(String[] args) {
		Queue<Integer> intQueue = new ArrayQueue<Integer>(10);

		
		for(int i=0; i<10; i++){
			intQueue.in(i);
		}

		System.out.println("before out " + intQueue);
		
		System.out.print("queue out ");
		for(int i=0; i<10; i++){
			System.out.print(intQueue.out() + " ");
		}
		
		System.out.println("");
		
		System.out.println("after out " + intQueue);
		
		//1000进入队列
		intQueue.in(1000);
		System.out.println(intQueue.getFirst());
		System.out.println(intQueue.getLast());
		System.out.println("after 1000 in queue and " + intQueue);
		
	}

}

输出结果

before out the queue size is 10 and the element is 0 1 2 3 4 5 6 7 8 9 
queue out 0 1 2 3 4 5 6 7 8 9 
after out the queue size is 0 and the element is null
1000
1000
after 1000 in queue and the queue size is 1 and the element is 1000 


上面使用数组实现的顺序队列,在使用上有着很大的闲置。因为会造成假溢出现象,并且长度是有限制的,不能动态的增长,而且在弹出元素时,算法效率低下...所以这种情况,可以使用循环队列。不过链式队列可以更加灵活的改善这些缺点,下面给出链式队列

package net.itaem.list.impl;

import net.itaem.list.Queue;

public class LinkedQueue<T> implements Queue<T> {

	private class Node<E>{
		private E data;
		private Node<E> next;

		public Node(E data, Node<E> next){
			this.data = data;
			this.next = next;
		}

		public E data(){
			return data;
		}
		
		public void setData(E data){
			this.data = data;
		}

		public Node<E> next(){
			return next;
		}

		public void setNext(Node<E> next){
			this.next = next;
		}
	}

	//定义头结点和尾节点
	private Node<T> first;
	private Node<T> last;

	//保存队列元素个数
	private int size;


	public LinkedQueue(){
		//初始化一个空的节点
		first = last = new Node<T>(null, null);	
	}

	@Override
	public void in(T e) {
		Node<T> newElement = new Node<T>(e, null);   //新建一个节点
		last.setNext(newElement);   //将节点添加到链表中
		last = newElement;   //修改尾节点指向新的节点
		size++;  //动态增长
	}

	@Override
	public T out() {
		//找到第一个节点
		Node<T> p = null;
		T result = null;

		if(first.next() != null){
			p = first.next();
			result = p.data();
			first.setNext(first.next().next());   //修改头元素
			size--;
		}else{
			throw new RuntimeException("队列为空,不能进行出队列操作");
		}

		if(p == last){
			last = first;   //该队列为空,需要将尾节点指向头结点	
		}

		//释放节点

		p = null;

		return result;
	}

	@Override
	public int size() {
		return size;
	}

	@Override
	public void clear() {
		Node<T> p = first;
		
		while((p = p.next()) != null){
			p.setData(null);   //释放应用
			p.setNext(null);   
		}

		size = 0;

		last = first;   //将尾节点指向头结点,代表队列为空
	}

	@Override
	public T getFirst() {
		T result = null;

		if(first.next() != null){
			result = first.next().data();
		}

		return result;
	}

	@Override
	public T getLast() {
		if(last.data() != null){
			return last.data();
		}else{
			return null;
		}
	}

	public String toString(){
		Node<T> p = first;
		StringBuilder sb = new StringBuilder();
		
		if(p.next() == null) sb.append("null");
		
		else
			while((p = p.next()) != null){
				sb.append(p.data() + " ");
			}
		return "queue size is " + size + " and the element is " + sb.toString();
	}
	
	public static void main(String[] args) {
		Queue<Integer> intQueue = new LinkedQueue<Integer>();
	    for(int i=0; i<10; i++){
	    	intQueue.in(i);
	    }
	    
	    System.out.println("before out\n " + intQueue);
	    
	    System.out.print("out queue ");
	    for(int i=0; i<10; i++){
	    	System.out.print(intQueue.out());
	    }
	    System.out.println("");
	    
	    System.out.println("after out " + intQueue);
	    
	    intQueue.in(1000);
	    
	    System.out.println("first and last is " + intQueue.getFirst() + " " + intQueue.getLast());
	    
	    System.out.println("1000 in " + intQueue);
	    
	    intQueue.clear();
	    System.out.println("after clear " + intQueue);
	    
	}

}

输出结果

before out
 queue size is 10 and the element is 0 1 2 3 4 5 6 7 8 9 
out queue 0123456789
after out queue size is 0 and the element is null
first and last is 1000 1000
1000 in queue size is 1 and the element is 1000 
after clear queue size is 0 and the element is null 


队列

标签:数据结构   java   教学   

原文地址:http://blog.csdn.net/u010469003/article/details/24771269

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!