单向队列和优先级队列

一、队列的概念

队列(queue)是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。

在比如在计算机操作系统中,有各种队列在安静的工作着,比如打印机在打印列队中等待打印。

队列和栈是相反的,栈是后进先出,队列是先进先出。

二、单向队列

队列的实现原理如下:

1,队列中的数据不总是从数组的0下标开始的,移除一些队头front的数据后,队头指针会指向一个较高的下标位置。

2,队列中新增一个数据时,队尾的指针rear 会向上移动,也就是向下标大的方向。移除数据项时,队头指针 front 也会向下移动。

3,队列有一个maxSize(最大尺寸),当队尾和队头超过时最大尺寸时,队尾和队列循环回到初始位置,此队列也称循环队列。

代码如下:

//单向队列实现
public class MyQueue {
	
	private Object[] queArray;//队列
	
	private int maxSize;//总大小
	
	private int head;//队首
	
	private int tail;//队尾
	
	
	private int nItems;//队列中的实际数目
	
	public MyQueue(int s) {
		this.maxSize = s;
		this.head = 0;
		this.tail = -1;
		this.queArray = new Object[maxSize];
		this.nItems = 0;
	}

	public void insert(int value) {
		if (isFull()) {
			System.out.println("队列已满");
			return;
		} else {
			//当尾端指向了顶部,循环会第一个元素
			if (tail == maxSize - 1) {
				tail = -1;
			}			
			queArray[++tail] = value;
			nItems++;			
		}
	}
	
	
	
	public void remove() {		
		if (!isEmpty()) {			
			queArray[head] = null;
			head++;
			if(head == maxSize) {
				head = 0;
			}
			nItems--;			
		}		
	}

	
	public Object peekFront() {
		return queArray[head];
	}
	
	public int getSize() {
		return nItems;
	}
	
	public Boolean isFull() {
		return (nItems == maxSize);
	}
	
	public Boolean isEmpty() {
		return (nItems == 0);
	}
	
	public Object[] getAll() {
		return queArray;
	}

}
测试类

public class MyQueueTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyQueue mq = new MyQueue(10);
		mq.insert(1);
		mq.insert(2);
		mq.insert(5);
		mq.insert(9);
		mq.insert(11);
		mq.insert(15);
		mq.insert(19);
		mq.insert(21);
		mq.insert(25);
		mq.insert(29);
		
		mq.remove();
		mq.remove();
		mq.insert(33);
		mq.insert(37);
		mq.remove();
		mq.remove();
		Object[] queue = mq.getAll();
		for (Object obj : queue) {
			System.out.println(obj == null ? null:obj.toString());
		}
	}

}

三、优先级队列

优先级队列(priority queue)是比栈和队列更专用的数据结构,在优先级队列中,数据项按照关键字进行排序,关键字最小(或者最大)的数据项往往在队列的最前面,而数据项在插入的时候都会插入到合适的位置以确保队列的有序。

优先级队列 是0个或多个元素的集合,每个元素都有一个优先权,对优先级队列执行的操作有:

  (1)查找

  (2)插入一个新元素

  (3)删除

一般情况下,查找操作用来搜索优先权最大的元素,删除操作用来删除该元素 。对于优先权相同的元素,可按先进先出次序处理或按任意优先权进行。

这里我们用数组实现优先级队列,这种方法插入比较慢,但是它比较简单,适用于数据量比较小并且不是特别注重插入速度的情况。

public class PriorityQue {
    private int maxSize;
    private int[] priQueArray;
    private int nItems;
     
    public PriorityQue(int s){
        maxSize = s;
        priQueArray = new int[maxSize];
        nItems = 0;
    }
     
    //插入数据
    public void insert(int value){
        int j;
        if(nItems == 0){
            priQueArray[nItems++] = value;
        }else{
            j = nItems -1;
            //选择的排序方法是插入排序,按照从大到小的顺序排列,越小的越在队列的顶端
            while(j >=0 && value > priQueArray[j]){
                priQueArray[j+1] = priQueArray[j];
                j--;
            }
            priQueArray[j+1] = value;
            nItems++;
        }
    }
     
    //移除数据,由于是按照大小排序的,所以移除数据我们指针向下移动
    //被移除的地方由于是int类型的,不能设置为null,这里的做法是设置为 -1
    public int remove(){
        int k = nItems -1;
        int value = priQueArray[k];
        priQueArray[k] = -1;//-1表示这个位置的数据被移除了
        nItems--;
        return value;
    }
     
    //查看优先级最高的元素
    public int peekMin(){
        return priQueArray[nItems-1];
    }
     
    //判断是否为空
    public boolean isEmpty(){
        return (nItems == 0);
    }
     
    //判断是否满了
    public boolean isFull(){
        return (nItems == maxSize);
    }
 
}

你可能感兴趣的:(java,队列,栈,数据结构,Java)