Java数据结构与算法解析(三)——队列与背包
来源:互联网 发布:晴天软件注册码 编辑:程序博客网 时间:2024/05/22 02:25
关联文章:
Java数据结构与算法解析(一)——表
Java数据结构与算法解析(二)——栈
队列基本概念
像栈一样,队列也是表。然而,使用队列时插入在一端进行,而删除则在另一端进行。插入的一端称为队尾,删除的一端称为队头 。其插入和删除的操作分别在表的两端进行,队列的特点就是先进先出(First In First Out)。
队列的数组实现
队列的顺序储存
缺点:出队复杂度高0(n),容易假溢出
Front为队头指针,rear为队尾指针,但是这种存储方式的缺点就是出队复杂度高0(n),容易假溢出,例如让a1,a2出队,则a1,a2存储的位置会被设置为null,然后将front进行移动,指向a3,容易假溢出是指,上图右边的情况,rear已经角标越界,说明要扩容,但是其实队列里有两个地方是空的,就是角标0和1的位置,这种就是假溢出现象
循环队列
把队列的头尾相接的循环存储结构叫做循环队列。
循环队列就可以很好的解决假溢出的现象
实现循环队列
声明队列的公用接口
public interface Queue<T> { int size(); boolean isEmpty(); void enqueue(T t); T dequeue();}
public class ArrayQueue<T> implements Queue<T> { private T[] mArray; private int mQueueSize; private int mFront; private int mLast; private static final int DEFAULT_CAPACITY = 10; public ArrayQueue(int capacity) { if (capacity < DEFAULT_CAPACITY) { ensureCapacity(DEFAULT_CAPACITY); } else { ensureCapacity(capacity); } } @Override public int size() { return mQueueSize; } @Override public boolean isEmpty() { return mFront == mLast; } @Override public boolean enqueue(T t) { //判断是否满队 if (mFront == (this.mLast + 1) % mArray.length) { ensureCapacity(mArray.length * 2 + 1); } mArray[mLast] = t; mLast = (mLast + 1) % mArray.length; mQueueSize++; return true; } private int findFirstEmptyIndex() { for (int i = 0; i < mArray.length; i++) { if (mArray[i] == null) { return i; } } } @Override public T dequeue() { if (mLast == mFront) { return null; } else { T t = mArray[mFront]; mFront = (mFront + 1) % mArray.length; return t; } } private void ensureCapacity(int newCapacity) { T[] newArray = (T[]) new Object[newCapacity]; for (int i = 0; i < mArray.length; i++) { newArray[i] = mArray[i]; } mArray = newArray; }}
队列的链式存储模式
实现队列的最好的方式就是使用单链表来实现,队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已。
这种实现出队和入队就十分方便,出队只需要将头结点指向的位置进行改变,入队只需要将rear的指向进行改变
空队列的图如下:
队列的链式实现
public class LinkedQueue<T> implements Queue<T> { //队列头指针 private Node<T> mFront; //队列尾指针 private Node<T> mRear; //队列长度 private int mSize = 0; public LinkedQueue() { Node n = new Node(null, null); mFront = mRear = n; } @Override public int size() { return mSize; } @Override public boolean isEmpty() { return mFront == mRear; } @Override public boolean enqueue(T t) { Node n = new Node(t, null); //将队尾指针指向新加入的节点,将s节点插入队尾 mFront.mNext = n; mRear = n; mSize++; return true; } @Override public T dequeue() { if (mRear == mFront) { throw new NoSuchElementException("The LinkedQueue is empty"); } Node<T> deleNote = mFront.mNext; T t = deleNote.mData; mFront.mNext = deleNote.mNext; //判断出队列长度是否为1 if (mFront.mNext == null) { mFront = mRear; } mSize--; return t; } private static class Node<T> { private Node<T> mNext; private T mData; public Node(T data, Node<T> next) { mData = data; mNext = next; } }}
背包的概念
背包是一种不支持从中删除元素的集合数据类型,它的目的就是帮助用例收集元素并迭代遍历所有收集到的元素,使用背包就说明元素的处理顺序不重要,可以想象一个背包,往里面放了N个小球,在取球的时候手伸进背包是随机取出来的,通常这样的数据结构用来进行计算平均值等对元素顺序没有要求的算法;
图1
背包的数组实现
public class ArrayBag<T> implements Iterable { private T[] mArray; private int mBagSize; private static final int DEFAULT_CAPACITY = 10; public ArrayBag() { ensureCapacity(DEFAULT_CAPACITY); } public ArrayBag(int bagSize) { if (bagSize > DEFAULT_CAPACITY) { ensureCapacity(bagSize); } else { ensureCapacity(DEFAULT_CAPACITY); } } public void add(T t) { if (mArray.length == mBagSize) { ensureCapacity(mArray.length); } mArray[mBagSize] = t; mBagSize++; } private void ensureCapacity(int newCapacity) { T[] newArray = (T[]) new Object[newCapacity]; for (int i = 0; i < mArray.length; i++) { newArray[i] = mArray[i]; } mArray = newArray; } @Override public Iterator iterator() { return new ArrayIterator(); } private class ArrayIterator implements Iterator<T> { private int currentPositon; @Override public boolean hasNext() { return currentPositon < mBagSize; } @Override public T next() { if (!hasNext()) { throw new NoSuchElementException(); } return mArray[currentPositon++]; } }}
背包的链表实现
public class LinkedBag<T> implements Iterable { private int mBagSize; private Node<T> headNote; public LinkedBag() { headNote = new Node<T>(null, null); } public void add(T t) { Node<T> node = new Node<T>(t, null); headNote.mNext = node; } @Override public Iterator iterator() { return new ArrayIterator(); } private class ArrayIterator implements Iterator<T> { private Node<T> currentNode = headNote.mNext; @Override public boolean hasNext() { return currentNode != null; } @Override public T next() { if (!hasNext()) { throw new NoSuchElementException(); } T t = currentNode.mData; currentNode = currentNode.mNext; return t; } } private static class Node<T> { private Node<T> mNext; private T mData; public Node(T data, Node<T> next) { mData = data; mNext = next; } }}
阅读全文
1 0
- Java数据结构与算法解析(三)——队列与背包
- Java数据结构与算法解析(三)——队列与背包
- Java数据结构与算法解析(十三)——优先级队列
- Java数据结构与算法解析(十三)——优先级队列
- Java数据结构与算法解析——优先级队列
- Java数据结构与算法解析(十三)——优先级队列
- Java数据结构与算法《三》栈与队列
- 学习JavaScript数据结构与算法(三)——队列
- Java数据结构与算法:队列
- Java数据结构与算法---队列
- java数据结构与算法-队列
- 数据结构与算法(java)——栈和队列
- 数据结构与算法(三)栈&&队列
- 数据结构与算法(三) 栈和队列
- 数据结构与算法——循环队列
- 数据结构与算法——链队列
- 数据结构与算法之—循环队列
- 【Java数据结构学习笔记之三】Java数据结构与算法之队列(Queue)实现
- JS事件委托(event delegation)
- 票根'ST-xxxxxx-cas'不符合目标服务的解决办法
- 美团一面
- 计算机系统要素-从零开始构建现代计算机 项目代码
- Linus实验楼笔记——第7节:文件系统操作与磁盘管理
- Java数据结构与算法解析(三)——队列与背包
- linux多台主机联网
- c++ 双向链表操作
- java中的三大集合遍历及foreach循环总结
- A Simple Problem with Integers POJ
- 垃圾回收算法
- 栈和队列的使用
- android studio 2.3.3 最新 中文 汉化包 韩梦飞沙 安卓工作室 美化包
- CentOS上tomcat启动巨慢问题