ARDeque
在本实验中,我们将使用an array实现deque
o在前两次作业中,我们使用链表实现了deque
我们还将使用泛型,以便deque可以存储任何类型的对象
o array的起始大小/长度必须为4
o使用resizing:在本节课讨论的数组加倍和数组减半
删除前,如果已满则加倍大小
删除后,如果大小小于或等于四分之一,则将大小减半
o使用循环数组,后面会有示例
o您可以定义和提交自己的private helper methods
例如:private void resize(int capacity)
上代码:
public class ARDeque<T> {
private T[] items;
private int size;
private int nextFirst;
private int nextLast;
/**
* @return the size of the array used in the deque.
*/
public int itemsLength() {
return items.length;
}
/**
* @return the number of items in the deque.
*/
public int size() {
return size;
}
/**
* @return true if deque is empty, false otherwise.
*/
public boolean isEmpty() {
return size == 0;
}
/*
***************************
* DO NOT MODIFY CODE ABOVE
***************************
*/
/*
******************* HELPER METHODS START *******************
***** Include your helper method(s) in EACH Submission *****
*********************** that uses it ***********************
*/
/* Resizes the underlying array to the target capacity. */
@SuppressWarnings("unchecked")
private void resize(int capacity) {
T[] newItems = (T[]) new Object[capacity];
int newFirst = capacity/2-1;
int newLast = newFirst+1;
int index = 0;
if(this.nextFirst != items.length-1) index = this.nextFirst+1;
for(int i=0;i<this.size;i++) {
T node = this.items[index];
newItems[newLast] = node;
if(newLast==newItems.length-1) newLast = 0;
else newLast += 1;
if(index == this.items.length-1) {
index = 0;
}else {
index += 1;
}
}
this.nextFirst = newFirst;
this.nextLast = newLast;
this.items = newItems;
}
/*
******************** HELPER METHODS END ********************
*/
// EXERCISE 10.1 EMPTY CONSTRUCTOR
/**
* Creates an empty deque.
*/
@SuppressWarnings("unchecked")
public ARDeque() {
items = (T[]) new Object[4];
this.nextFirst = 2;
this.nextLast = 3;
this.size = 0;
}
// EXERCISE 10.2 ADD TO BACK
/**
* Adds an item of type T to the back of the deque.
* @param item is a type T object to be added.
*/
public void addLast(T item) {
if(this.size==this.items.length) resize(this.items.length*2);
this.items[nextLast] = item;
if(this.nextLast==this.items.length-1) {
this.nextLast = 0;
}else {
this.nextLast += 1;
}
this.size += 1;
}
// EXERCISE 10.3 PRINT ITEMS
/**
* Prints the items in the deque from first to last,
* separated by a space, ended with a new line.
*/
public void printDeque() {
if(this.size==0){
System.out.print("\n");
return;
}
int index = 0;
if(this.nextFirst != items.length-1) index = this.nextFirst+1;
for(int i=0;i<this.size;i++) {
if(i==this.size-1) {
System.out.print(items[index]);
System.out.print("\n");
}else {
System.out.print(items[index]+" ");
}
if(index == this.items.length-1) {
index = 0;
}else {
index += 1;
}
}
}
// EXERCISE 10.4 GET ITEM
/**
* Gets the item at the given index.
* Does not mutate the deque.
* @param index is an index where 0 is the front.
* @return the index-th item of the deque.
* @throws IndexOutOfBoundsException if no item exists at the given index.
*/
public T get(int index) {
if(this.size==0) {
throw new IndexOutOfBoundsException("Index "+index+" is not valid");
}
if(index<0||index>=this.size) {
throw new IndexOutOfBoundsException("Index "+index+" is not valid");
}else {
if(index+this.nextFirst+1>=this.items.length) {
int add = index-(this.items.length-this.nextFirst-1);
T node = this.items[add];
return node;
}else {
T node = this.items[index+this.nextFirst+1];
return node;
}
}
}
// ASSIGNMENT 10.1 ADD TO FRONT
/**
* Adds an item of type T to the front of the deque.
* @param item is a type T object to be added.
*/
public void addFirst(T item) {
if(this.size==this.items.length) resize(this.items.length*2);
this.items[this.nextFirst] = item;
if(this.nextFirst==0){
this.nextFirst = this.items.length-1;
}else {
this.nextFirst -= 1;
}
this.size += 1;
}
// ASSIGNMENT 10.2 DELETE FRONT
/**
* Deletes and returns the item at the front of the deque.
* If no such item exists, returns null.
* @return the first item of the deque, null if it does not exist.
*/
public T delFirst() {
if(this.size==0) {
return null;
}
int delIndex = this.nextFirst+1;
if(this.nextFirst==(this.items.length-1)) delIndex = 0;
T node = this.items[delIndex];
this.items[delIndex] = null;
this.nextFirst = delIndex;
this.size -= 1;
if(this.size<=(this.items.length/4)) resize(this.items.length/2);
return node;
}
// ASSIGNMENT 10.3 DELETE BACK
/**
* Deletes and returns the item at the back of the deque.
* If no such item exists, returns null.
* @return the last item of the deque, null if it does not exist.
*/
public T delLast() {
if(this.size==0) {
return null;
}
int delIndex = this.nextLast-1;
if(this.nextLast == 0) delIndex = this.items.length-1;
T node = this.items[delIndex];
this.items[delIndex] = null;
this.nextLast = delIndex;
this.size -= 1;
if(this.size<=(this.items.length/4)) resize(this.items.length/2);
return node;
}
// ASSIGNMENT 10.4 COPY CONSTRUCTOR
/**
* Creates a (deep) copy of another Deque object.
* @param other is another ARDeque<T> object.
*/
public ARDeque(ARDeque<T> other) {
if(other.size==0) {
this.items = (T[]) new Object[4];
this.nextFirst = 2;
this.nextLast = 3;
this.size = 0;
}else {
this.items = (T[]) new Object[other.itemsLength()];
this.nextFirst = other.itemsLength()/2-1;
this.nextLast = this.nextFirst+1;
this.size = other.size();
for(int i=0;i<other.size();i++) {
T node = (T)(other.get(i));
this.items[this.nextFirst] = node;
if(this.nextFirst==0){
this.nextFirst = this.items.length-1;
}else {
this.nextFirst -= 1;
}
this.size += 1;
}
}
}
}