キューとは
キューは特殊な線形テーブルです。操作はヘッドと
テールの両端でのみ入力できます。リア:キューの
先頭と呼ばれるキューの最後からのみ要素を追加します。から要素を取り出したり削除したりすることのみができます。キューの先頭。、先入れ先出しの原則でチームを呼び出す
:先入れ先出しFIFO
食堂に並んで私たちの生活の中で食べ物を買うようなものです。最初の人が最初に食べ物を購入し、後の人が列の最後に並んでいます。
キューインターフェイスの設計
int size(); //要素の数
boolean(); //空かどうかvoidclear(); //要素を
クリア
voidenQueue(E element); //
Enqueue E deQueue(); // Dequeue
E front(); //キューのhead要素を取得します
**
リンクリストを使用してキューを実装する
LinkedListソースコード
package list;
import list.AbstractList;
public class LinkedList<E> extends AbstractList<E> {
private Node<E> first;
private Node<E> last;
private static class Node<E> {
E element;
Node<E> prev;
Node<E> next;
public Node(Node<E> prev, E element, Node<E> next) {
this.prev = prev;
this.element = element;
this.next = next;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
if (prev != null) {
sb.append(prev.element);
} else {
sb.append("null");
}
sb.append("_").append(element).append("_");
if (next != null) {
sb.append(next.element);
} else {
sb.append("null");
}
return sb.toString();
}
}
@Override
public void clear() {
size = 0;
first = null;
last = null;
}
@Override
public E get(int index) {
return node(index).element;
}
@Override
public E set(int index, E element) {
Node<E> node = node(index);
E old = node.element;
node.element = element;
return old;
}
@Override
public void add(int index, E element) {
rangeCheckForAdd(index);
// size == 0
// index == 0
if (index == size) { // 往最后面添加元素
Node<E> oldLast = last;
last = new Node<E>(oldLast, element, null);
if (oldLast == null) { // 这是链表添加的第一个元素
first = last;
} else {
oldLast.next = last;
}
} else {
Node<E> next = node(index);
Node<E> prev = next.prev;
Node<E> node = new Node<E>(prev, element, next);
next.prev = node;
if (prev == null) { // index == 0
first = node;
} else {
prev.next = node;
}
}
size++;
}
@Override
public E remove(int index) {
rangeCheck(index);
Node<E> node = node(index);
Node<E> prev = node.prev;
Node<E> next = node.next;
if (prev == null) { // index == 0
first = next;
} else {
prev.next = next;
}
if (next == null) { // index == size - 1
last = prev;
} else {
next.prev = prev;
}
size--;
return node.element;
}
@Override
public int indexOf(E element) {
if (element == null) {
Node<E> node = first;
for (int i = 0; i < size; i++) {
if (node.element == null) return i;
node = node.next;
}
} else {
Node<E> node = first;
for (int i = 0; i < size; i++) {
if (element.equals(node.element)) return i;
node = node.next;
}
}
return ELEMENT_NOT_FOUND;
}
/**
* 获取index位置对应的节点对象
* @param index
* @return
*/
private Node<E> node(int index) {
rangeCheck(index);
if (index < (size >> 1)) {
Node<E> node = first;
for (int i = 0; i < index; i++) {
node = node.next;
}
return node;
} else {
Node<E> node = last;
for (int i = size - 1; i > index; i--) {
node = node.prev;
}
return node;
}
}
@Override
public String toString() {
StringBuilder string = new StringBuilder();
string.append("size=").append(size).append(", [");
Node<E> node = first;
for (int i = 0; i < size; i++) {
if (i != 0) {
string.append(", ");
}
string.append(node);
node = node.next;
}
string.append("]");
return string.toString();
}
}
キューの実装
import com.sun.xml.internal.fastinfoset.util.ValueArrayResourceException;
import list.LinkedList;
import list.List;
public class Queue<E>{
private List<E> list=new LinkedList<E>();
//元素的数量
public int size (){
return list.size();
}
//是否为空
public boolean isEmpty(){
return list.isEmpty();
}
//清空元素
public void clear(){
list.clear();
}
//入队
public void enQueue(E element){
list.add(element); ;
}
//出队
public E deQueue(){
return list.remove(0);
}
//获取队列的头元素
public E front(){
return list.get(0);
}
}
Dequeの実装
dequeとは
チームの先頭と末尾でキューを追加および削除できます
int size(); //元素的数量
boolean(); //是否为空
void clear();//清空元素
void enQueue(E element);//入队
E deQueue(); //出队
E front();//获取队列的头元素
以下の方法は、上記の元の方法よりも多くなります
void enQueueRear(E element) //从队尾入队
E deQueeuRear() //从队尾出队
void enQueueFront() ///从队头入队
void rear(); //获取队尾元素
Dequeuソースコードの実装
リンクリストのソースコードは上記と同じです
import list.LinkedList;
import list.List;
public class Deque<E> {
private List<E> list=new LinkedList<E>();
//元素的数量
public int size (){
return list.size();
}
//是否为空
public boolean isEmpty(){
return list.isEmpty();
}
//清空元素
public void clear(){
list.clear();
}
//入队
public void enQueue(E element){
list.add(element); ;
}
//出队
public E deQueue(){
return list.remove(0);
}
//获取队列的头元素
public E front(){
return list.get(0);
}
/*从队尾入队*/
public void enQueueRear(E element) {
list.add(element);
}
/*从队尾出队*/
public E deQueueRear() {
return list.remove(list.size() - 1);
}
/*获取队尾元素*/
public E rear() {
return list.get(list.size() - 1);
}
/*从队头入队*/
public void enQueueFront(E element){
list.add(0,element);
}
}
循環キュー
一般的な紹介
キューの最下層は配列で実装でき、最適化されたキューは循環キューとも呼ばれます。つまり、リソースを無駄にすることなくスペースを最大限に活用できます。
要素を削除する
2つの要素と1つの要素を追加します
現時点では、キューの後ろにスペースはありませんが、前にスペースがあります
要素を追加する
これは循環キューの一般的な実装であり、配列のスペースが無駄にならないようにするのに十分です。
ソースコードの実装
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.omg.IOP.ENCODING_CDR_ENCAPS;
import javax.print.DocFlavor;
import java.security.interfaces.ECKey;
import java.util.EventListener;
public class CircleQueue<E> {
private int front;
private int size;
/*存储元素的数组*/
private E[] elements;
/*默认数组大小*/
private static final int DEFAULT_CAPACITY = 10;
/*构造方法*/
public CircleQueue() {
E[] es = (E[]) new Object[DEFAULT_CAPACITY];
}
//返回队列的大小
public int size() {
return size;
}
/*判断队列是否为空*/
public boolean isEmpty() {
return size == 0;
}
/*清除队列*/
public void clear() {
/*将数组元素设置为null*/
for (int i = 0; i < size; i++) {
elements[index(i)]=null;
}
/*头元素与size都置为0*/
front=0;
size=0;
}
/*元素入队*/
public void enQueue(E element) {
ensureCapacity(size+1);
elements[index(size)]=element;
size++;
}
/*元素出队*/
public E deQueue() {
/*保存队首元素*/
E element = elements[front];
/*队首元素置为null*/
elements[front]=null;
/*获取新的队首元素所在的地方*/
front=(index(1));
size--;
return element;
}
/*获取头元素*/
public E front() {
return elements[front];
}
@Override
public String toString() {
StringBuilder string = new StringBuilder();
string.append("capcacity=").append(elements.length)
.append(" size=").append(size)
.append(" front=").append(front)
.append(", [");
for (int i = 0; i < elements.length; i++) {
if (i != 0) {
string.append(", ");
}
string.append(elements[i]);
}
string.append("]");
return string.toString();
}
/*索引映射封装*/
private int index(int index) {
index+=front;
return index-(index>= elements.length?elements.length:0);
}
/**
* 保证要有capacity的容量
* @param capacity
*/
private void ensureCapacity(int capacity) {
int oldCapacity = elements.length;
if (oldCapacity>=capacity){
int newCapacity=oldCapacity+(oldCapacity>>1);
E[] newElements = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
newElements[i]=elements[index(size)];
}
elements=newElements;
front=0;
}
}
}
キーメソッド
インデックスマッピングのカプセル化
単純なモジュロ演算ですが、ここでは足し算と引き算の方法を使って実装しました。コンピュータシステムの基礎を学んだ学生は、これがより効率的であることを知っています。現在のインデックス値+フロント値が現在よりも大きい場合配列の長さ、値が配列の先頭にあることを示します
private int index(int index) {
index+=front;
return index-(index>= elements.length?elements.length:0);
}
配列拡張
private void ensureCapacity(int capacity) {
int oldCapacity = elements.length;
if (oldCapacity >= capacity) return;
// 新容量为旧容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
E[] newElements = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
newElements[i] = elements[index(i)];
}
elements = newElements;
// 重置front
front = 0;
}
両端循環キュー
package com.mj.circle;
@SuppressWarnings("unchecked")
public class CircleDeque<E> {
private int front;
private int size;
private E[] elements;
private static final int DEFAULT_CAPACITY = 10;
public CircleDeque() {
elements = (E[]) new Object[DEFAULT_CAPACITY];
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public void clear() {
for (int i = 0; i < size; i++) {
elements[index(i)] = null;
}
front = 0;
size = 0;
}
/**
* 从尾部入队
* @param element
*/
public void enQueueRear(E element) {
ensureCapacity(size + 1);
elements[index(size)] = element;
size++;
}
/**
* 从头部出队
* @param element
*/
public E deQueueFront() {
E frontElement = elements[front];
elements[front] = null;
front = index(1);
size--;
return frontElement;
}
/**
* 从头部入队
* @param element
*/
public void enQueueFront(E element) {
ensureCapacity(size + 1);
front = index(-1);
elements[front] = element;
size++;
}
/**
* 从尾部出队
* @param element
*/
public E deQueueRear() {
int rearIndex = index(size - 1);
E rear = elements[rearIndex];
elements[rearIndex] = null;
size--;
return rear;
}
public E front() {
return elements[front];
}
public E rear() {
return elements[index(size - 1)];
}
@Override
public String toString() {
StringBuilder string = new StringBuilder();
string.append("capcacity=").append(elements.length)
.append(" size=").append(size)
.append(" front=").append(front)
.append(", [");
for (int i = 0; i < elements.length; i++) {
if (i != 0) {
string.append(", ");
}
string.append(elements[i]);
}
string.append("]");
return string.toString();
}
private int index(int index) {
index += front;
if (index < 0) {
return index + elements.length;
}
return index - (index >= elements.length ? elements.length : 0);
}
/**
* 保证要有capacity的容量
* @param capacity
*/
private void ensureCapacity(int capacity) {
int oldCapacity = elements.length;
if (oldCapacity >= capacity) return;
// 新容量为旧容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
E[] newElements = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
newElements[i] = elements[index(i)];
}
elements = newElements;
// 重置front
front = 0;
}
}