Algs4-1.3.33一个双向队列Deque的可变长环形数组实现
1.3.33Deque。一个双向队列(或者称为deque)和栈或队列类似,但它同时支持在两端添加或删除元素。Deque能够存储一组元素并支持表1.3.9中的API:
表1.3.9泛型双向队列的API
public class Deque<Item> implements Iterable<Item>
Deque()//创建空双向队列
boolean isEmpty()//双向队列是否为空
int size()//双向队列中的元素数量
void pushLeft(Item item)//向左端添加一个新元素
void pushRight(Item item)//向右端添加一个新元素
Item popLeft() 从左端删除一个元素
Item popRight()从右端删除一个元素
编写一个使用动态数组调整实现这份API的ResizeArrayDeque类。
答:环形时无论left<right 还是right>left,pushLeft 均为left--,pushRight均为right++,popLeft均为left++,popRight均为right--,当left或right值为-1时值置为 array.length-1,当left或right值为array.length时值置为0。
import java.util.Iterator;
public class ResizeArrayDeque<Item> implements Iterable<Item>
{
private Item[] a=(Item[]) new Object[1];
private int N;
private int left;
private int right;
public ResizeArrayDeque()
{
left=0;
right=0;
N=0;
}
public boolean isEmpty()
{return N==0;}
public int size()
{return N;}
public void pushLeft(Item item)
{
if(N==a.length) resize(2*N);
left--;
if(left==-1) left=a.length-1;
a[left]=item;
if(isEmpty()) right=left;
N++;
}
public void pushRight(Item item)
{
if(N==a.length) resize(2*N);
right++;
if(right==a.length) right=0;
a[right]=item;
if(isEmpty()) left=right;
N++;
}
public Item popLeft()
{
Item item;
if(size()==0)
{
item=null;
}
else if(size()==1)
{
item=a[left];
N--;
}
else
{
item=a[left];
left++;
if(left==a.length) left=0;
N--;
if(N==a.length/4) resize(2*N);
}
return item;
}
public Item popRight()
{
Item item;
if(size()==0)
{
item=null;
}
else if(size()==1)
{
item=a[right];
N--;
}
else
{
item=a[right];
right--;
if(right==-1) right=a.length-1;
N--;
if(N==a.length/4) resize(2*N);
}
return item;
}
private void resize(int max)
{
Item[] temp=(Item[]) new Object[max];
int j=left;
for(int i=0;i<N;i++)
{
temp[i]=a[j];
j++;
if(j==a.length) j=0;
}
a=temp;
left=0;
right=N-1;
}
public Iterator<Item> iterator() {return new ListIterator();}
private class ListIterator implements Iterator<Item>
{
private int current=left;
public boolean hasNext(){return current!=right+1;}
public void remove(){}
public Item next()
{
Item item=a[current];
current++;
if(current==a.length) current=0;
return item;
}//end next
}//end class ListIterator
public static void main(String[] args)
{
ResizeArrayDeque<String> q=new ResizeArrayDeque<String>();
In in1=new In(args[0]);
In in2=new In(args[0]);
In in3=new In(args[0]);
In in4=new In(args[0]);
//pushLeft and popLeft
while(!in1.isEmpty())
{
String item=in1.readString();
q.pushLeft(item);
}
StdOut.printf("\n---pushLeft and for each Deque---\n");
for(String i:q)
StdOut.print(i+" ");
StdOut.printf("\n---pushLeft and popLeft---\n");
while(!q.isEmpty())
{
StdOut.print(q.popLeft()+" ");
}
//pushLeft and popRight
StdOut.printf("\n---pushLeft and popRight---\n");
while(!in2.isEmpty())
{
String item=in2.readString();
q.pushLeft(item);
}
while(!q.isEmpty())
{
StdOut.print(q.popRight()+" ");
}
//pushRight and popLeft
StdOut.printf("\n---pushRight and popLeft---\n");
while(!in3.isEmpty())
{
String item=in3.readString();
q.pushRight(item);
}
while(!q.isEmpty())
{
StdOut.print(q.popLeft()+" ");
}
//pushRight and popRight
StdOut.printf("\n---pushRight and popRight---\n");
while(!in4.isEmpty())
{
String item=in4.readString();
q.pushRight(item);
}
while(!q.isEmpty())
{
StdOut.print(q.popRight()+" ");
}
}
}
表1.3.9泛型双向队列的API
public class Deque<Item> implements Iterable<Item>
Deque()//创建空双向队列
boolean isEmpty()//双向队列是否为空
int size()//双向队列中的元素数量
void pushLeft(Item item)//向左端添加一个新元素
void pushRight(Item item)//向右端添加一个新元素
Item popLeft() 从左端删除一个元素
Item popRight()从右端删除一个元素
编写一个使用动态数组调整实现这份API的ResizeArrayDeque类。
答:环形时无论left<right 还是right>left,pushLeft 均为left--,pushRight均为right++,popLeft均为left++,popRight均为right--,当left或right值为-1时值置为 array.length-1,当left或right值为array.length时值置为0。
import java.util.Iterator;
public class ResizeArrayDeque<Item> implements Iterable<Item>
{
private Item[] a=(Item[]) new Object[1];
private int N;
private int left;
private int right;
public ResizeArrayDeque()
{
left=0;
right=0;
N=0;
}
public boolean isEmpty()
{return N==0;}
public int size()
{return N;}
public void pushLeft(Item item)
{
if(N==a.length) resize(2*N);
left--;
if(left==-1) left=a.length-1;
a[left]=item;
if(isEmpty()) right=left;
N++;
}
public void pushRight(Item item)
{
if(N==a.length) resize(2*N);
right++;
if(right==a.length) right=0;
a[right]=item;
if(isEmpty()) left=right;
N++;
}
public Item popLeft()
{
Item item;
if(size()==0)
{
item=null;
}
else if(size()==1)
{
item=a[left];
N--;
}
else
{
item=a[left];
left++;
if(left==a.length) left=0;
N--;
if(N==a.length/4) resize(2*N);
}
return item;
}
public Item popRight()
{
Item item;
if(size()==0)
{
item=null;
}
else if(size()==1)
{
item=a[right];
N--;
}
else
{
item=a[right];
right--;
if(right==-1) right=a.length-1;
N--;
if(N==a.length/4) resize(2*N);
}
return item;
}
private void resize(int max)
{
Item[] temp=(Item[]) new Object[max];
int j=left;
for(int i=0;i<N;i++)
{
temp[i]=a[j];
j++;
if(j==a.length) j=0;
}
a=temp;
left=0;
right=N-1;
}
public Iterator<Item> iterator() {return new ListIterator();}
private class ListIterator implements Iterator<Item>
{
private int current=left;
public boolean hasNext(){return current!=right+1;}
public void remove(){}
public Item next()
{
Item item=a[current];
current++;
if(current==a.length) current=0;
return item;
}//end next
}//end class ListIterator
public static void main(String[] args)
{
ResizeArrayDeque<String> q=new ResizeArrayDeque<String>();
In in1=new In(args[0]);
In in2=new In(args[0]);
In in3=new In(args[0]);
In in4=new In(args[0]);
//pushLeft and popLeft
while(!in1.isEmpty())
{
String item=in1.readString();
q.pushLeft(item);
}
StdOut.printf("\n---pushLeft and for each Deque---\n");
for(String i:q)
StdOut.print(i+" ");
StdOut.printf("\n---pushLeft and popLeft---\n");
while(!q.isEmpty())
{
StdOut.print(q.popLeft()+" ");
}
//pushLeft and popRight
StdOut.printf("\n---pushLeft and popRight---\n");
while(!in2.isEmpty())
{
String item=in2.readString();
q.pushLeft(item);
}
while(!q.isEmpty())
{
StdOut.print(q.popRight()+" ");
}
//pushRight and popLeft
StdOut.printf("\n---pushRight and popLeft---\n");
while(!in3.isEmpty())
{
String item=in3.readString();
q.pushRight(item);
}
while(!q.isEmpty())
{
StdOut.print(q.popLeft()+" ");
}
//pushRight and popRight
StdOut.printf("\n---pushRight and popRight---\n");
while(!in4.isEmpty())
{
String item=in4.readString();
q.pushRight(item);
}
while(!q.isEmpty())
{
StdOut.print(q.popRight()+" ");
}
}
}