队列(一)-------顺序队列

基本定义:一种特殊的线性表, 只允许在表的前端front进行删除操作, 只允许在后端rear 进行插入操作。进行插入的端叫做队尾,进行删除的一段叫做队头 。 ---- 先进先出的原则  FIFO

既然有固定的顺序操作  所以提供的大概有如下的操作:
 * init 初始化 :通常是一个构造器, 用于创建一个空队列
 * length : 返回队列中元素的个数
 * insert : 向队尾rear 插入一个数据  length + 1
 * delete : 在对头front 删除一个数据 length - 1
 * 访问前端元素 : 返回front 端的数据元素,但是不删除它
 * isEmpty() : 空 - true 否则 false
 * 清空 clear :将队列清空
实现它的数据结构:采用一组地址连续的存储单元一次存放队列从rear --> front的所有数据元素。程序只需要front和rear两个整型变量来记录front和rear端的元素索引。顺序存储结构的队列叫做顺序队列(SequenceQueue)。

参考代码部分:
public class SequenceQueue<T> {

	private int DEFAULT_SIZE = 20;
	//记录数组的长度或者说容量
	private int length;
	//定义一个数组来存储这个队列的元素
	private Object[] elementData;
	//保存当前顺序队列的个数
	private int front = 0;
	private int rear = 0;
	
	//根据默认的长度构建一个顺序队列
	public SequenceQueue(){
		this.length = DEFAULT_SIZE;
		elementData = new Object[length];
	}
	
	//以一个初始元素建立顺序队列
	public SequenceQueue(T data){
		this();
		elementData[0] = data;
		rear ++;
	}
	
	//以一个初始元素和指定的长度建立顺序队列   data相当于指定的第一个元素, initSize 指定顺序队列底层数组的长度
	public SequenceQueue(T data, int initSize){
		this.length = initSize;
		elementData = new Object[length];
		elementData[0] = data;
		rear ++;
	}

	//插入队列
	public void insert(T data){
		if(rear > length -1){
			throw new IndexOutOfBoundsException("队列已满!");
		}
		elementData[rear++] = data;
	}
	
	//移除或者删除队列
	public T remove(){
		if(empty()){
			throw new IndexOutOfBoundsException("空队列!");
		}
		//队列front端的元素值
		T oldValue = (T)elementData[front];
		//释放队列front端的元素
		elementData[front++] = null;
		return oldValue;
	}
	
	//判断是否为空队列
	private boolean empty() {
		// TODO Auto-generated method stub
		return rear == front;
	}
	
	//获取队列大小
	public int length(){
		return rear - front;
	}
	
	//返回队头的元素
	public T getElement(){
		if(empty()){
			throw new IndexOutOfBoundsException("空队列!");
		}
		return (T)elementData[front];
	}
	
	//清空队列
	public void clear(){
		//将底层的数组所有元素赋值为Null
		Arrays.fill(elementData, null);
		front = 0;
		rear = 0;
	}
	
	public String toString(){
		if(empty()){
			return "[]";
		}
		else{
			StringBuffer sb = new StringBuffer("[");
			for(int i = front ; i < rear ; i ++){
				sb.append(elementData[i].toString() + ", ");
			}
			int len = sb.length();
			return sb.delete(len - 2, len).append("]").toString();
		}
	}
}
测试部分和截图:
public static void main(String[] args) {
		
		SequenceQueue<String> sq = new SequenceQueue<String>();
		sq.insert("aa");
		sq.insert("bb");
		sq.insert("cc");
		sq.insert("dd");
		System.out.println(sq);
		System.out.println("输出队头元素:" + sq.getElement());
		System.out.println("移除队头元素:" + sq.remove());
		System.out.println(sq);
	}
对于顺序队列来说,因为底层是使用数组存储队列元素,每个队列元素在数组中的位置是固定的,改变的只是rear和front的值而已。当rear的值等于数组的大小,再试图添加元素时,会引起队列已满的异常。但是此时的这个异常可以称为“假满”的现象,数组依旧有空位,只是程序加不进去。

解决方案:1.“整体搬家”。每次将元素移出队列的时候都将队列中的所有元素向front端移动一位。这种方式下front值永远保持为0,元素插入队列时rear + 1, 元素移出队列时rear - 1。但是很明显浪费时间。
2.“循环队列”。就是将存储区堪称首尾相连的环形区域,当达到数组最大长时, rear的值再次变为0。  
此方法是我们接下来将要介绍的,请参看: 点击打开链接

参考: 《疯狂java 突破程序员基本功的16课》

以上是这篇的主要内容,如有错误或需要改进之处,请指教。谢谢!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值