队列的简单学习
来源:互联网 发布:护理优化服务流程 编辑:程序博客网 时间:2024/06/05 08:27
队列
队列也是一种有序数据项构成的数据结构,和栈不相同的是,操作队列的数据项是一边进一边出,只能在队尾(rear)插入数据项在队头(front)移出数据项并且栈的数据项是后进先出(last in first out),而队列是先进先出(first in fisrt out)。
可以用数组简单实现一个队列,定义两个下标front和rear代表队列的首尾,数据项存储在数组中的data[front]…data[rear]。
队列的存储方式也有两种可以选择:
1.让下标front恒为数组data的起始位置data[0],每次有元素出列,让后面的元素不断往前移。
2.让队列形成一个类似环的结构,当不断有元素出列,front下标前的空间被空出来;又不断有元素进列,当rear走到数组的末端的时候,就可以利用front前端的空间,重新再利用空间。也就是说队列的第一个元素紧跟着最后一个元素的后面,而队列最后一个元素的下一个元素就是队列的第一个元素。这种方式相对第一种效率就比较高一些。
假设现在有个data数组实现的队列,已经有A、B两个元素进入队列,front指向下标0,rear指向下标1。
当再加入C、D、E三个元素又将A出列,队列如下图所示
这时候front指向下标1,rear指向下标4。
当再添加一个元素F,此时rear已经到达了数据的末端,而front前端的空间是可以利用的,所以元素F就插到前面去了。
此时front指向下标1,而rear则指向下标0。
下面是队列的简单实现
public class ArrayQueue<E> implements Cloneable{ private E[] data; //存放队列的元素 private int items; //队列元素的个数 private int front; //队列的队头位置 private int rear; //队列的队尾位置 //当实例化一个队列的时候,给队列一个长度为INITIAL_LENGTH public ArrayQueue(){ final int INITIAL_LENGTH = 10; items = 0; data = (E[]) new Object[INITIAL_LENGTH]; } //手动给队列一个初始长度 public ArrayQueue(int initialLength){ if(initialLength < 0) throw new IllegalArgumentException("队列初始长度不能为负数!"); items = 0; data = (E[]) new Object[initialLength]; } //判断队列是否为空 public boolean isEmpty(){ return (items == 0); } //获取队列的长度 public int getLength(){ return data.length; } //获取队列元素个数 public int itemsSize(){ return items; } //修改队列的长度 public void changeLength(int newLength){ E[] newQueue; int index1, index2; if(data.length >= newLength) return; else if(items == 0) data = (E[]) new Object[newLength]; //如果现有队列是个小队列,那么新建一个队列把数据项都复制过去 else if(front < rear){ newQueue = (E[]) new Object[newLength]; System.arraycopy(data, front, newQueue, front, items); data = newQueue; } //现有队列形成了一个类似环的结构,分段处理两端的数据到新的队列 else{ newQueue = (E[]) new Object[newLength]; index1 = data.length - front; index2 = rear + 1; System.arraycopy(data, front, newQueue, 0, index1); System.arraycopy(data, 0, newQueue, index1, index2); front = 0; rear = items - 1; data = newQueue; } } //实现Cloneable的clone方法 public ArrayQueue<E> clone(){ ArrayQueue<E> queueCopy; try{ queueCopy = (ArrayQueue<E>) super.clone(); } catch(CloneNotSupportedException e){ throw new RuntimeException("复制失败!这个数据类型没有实现clone方法!") } queueCopy.data = data.clone(); return queueCopy; }}
下面就是数据项在队列中是如何入列跟出列的方法实现:
//将新元素添加到队列中 public void add(E newItem){ if(items == data.length) changeLength(2*items - 1); if(items == 0){ front = 0; rear = 0; } else{ //定义一个队尾下标后移的辅助方法 rear = nextIndex(rear); } data[rear] = newItem; items++; } //队尾下标后移的辅助方法 private int nextIndex(int i){ if(++i == data.length) return 0; else return i; } //将元素出列 public E remove(){ E head; if(items == 0) throw new NoSuchElementException("队列为空!"); head = data[front]; front = nextIndex(front); items--; return head; } //和栈一样,因为将元素添加到队列的时候改变了队列的大小,所以要把它恢复到实际大小 public void trimToSize(){ ArrayQueue<E> newQueue; if(items == data.length) return; else if(items == 0) data.length = 0; else if(front < rear){ newQueue = (E[]) new Object[items]; System.arraycopy(data, front, newQueue, items); data = newQueue; } else{ newQueue = (E[]) new Object[items]; int index1 = data.length - front; int index2 = rear + 1; System.arraycopy(data, front, newQueue, index1); System.arraycopy(data, 0, newQueue, index1, index2); front = 0; rear = items - 1; data = newQueue; } }
和栈一样,队列也能用链表实现,实现的方式跟数组的实现方式是相近的。
public class LinkedQueue<E> implements Cloneable{ private int nodes; private Node<E> front; private Node<E> rear; //初始化队列的头尾引用为空 public LinkedQueue(){ front = null; rear = null; } //判断队列是否为空 public boolean isEmpty(){ return (nodes == 0); } //获取队列元素个数 public int nodeSize(){ return nodes; } //获取当前队列的一个副本,返回副本的头尾引用 public LinkedQueue<E> clone(){ Node[] copyInfo; LinkedQueue<E> queueCopy = new LinkedQueue<E>(); copyInfo = Node.listCopyWithArray(front); queueCopy.front = copyInfo[0]; queueCopy.rear = copyInfo[1]; return copyInfo; }} //将元素入列 public void add(E newNode){ if(isEmpty()){ front = new Node<E>(newNode, null); rear = front; } else{ rear.addNodeAfter(newNode); rear = rear.getLink(); } nodes++; } //将元素出列 public E remove(){ E head; if(nodes == 0) throw new NoSuchElementException("队列不能为空!"); head = front.getData(); front = front.getLink(); nodes--; if(nodes == 0) rear = null; return head; }
- 队列的简单学习
- 学习笔记----容器中的队列的简单的使用
- 小佳弱弱学习——queue队列的简单实现
- 数据结构学习三(一个简单的队列实现)
- 队列的简单操作
- 队列的简单操作
- 队列的简单实现
- 队列的简单实现
- 队列的简单封装
- 队列的简单实现
- 队列的简单应用
- 一个简单的队列
- 队列的简单实现
- 队列的简单介绍
- 队列、优先队列的学习
- 队列的简单的操作
- 关于队列的简单操作
- 顺序队列的简单实现
- 深入理解Java的接口和抽象类
- 解决F/libc ( 953): Fatal signal 11 (SIGSEGV) at 0x00000003 (code=1), thread 1720 问题
- Java多线程:ThreadPoolExecutor详解
- 欢迎使用CSDN-markdown编辑器
- 第六周【数据结构实践项目——栈 (项目2 - 建立链栈算法库)】
- 队列的简单学习
- NavigationBar 添加、标题/左右按钮/颜色
- Anko for Android
- Android ,TextView 设置onClick 没反应
- SVN执行清理时乱码
- $1 Unistroke Recognizer( lua )
- iOS9 新特性
- CSDN-markdown编辑器使用规范
- 什么是JavaScript?