2.3.20非递归的快速排序。实现一个非递归的快速排序,使用一个循环来将弹出栈的子数组切分并将结果子数组重新压入栈。注意:先将较大的子数组压入栈,这样就可以保证栈最多只会有lgN个元素。
public class E2d3d20
{
//一个用记录子数组开始与结束索引的类
private class ArrayFromTo
{
int lo;
int hi;
}
//一个用来记录所子数组的栈
private Stack<ArrayFromTo> s=new Stack<ArrayFromTo>();
public void sort(Comparable[] a)
{
StdRandom.shuffle(a);
//初始数组只有0个或1个元素时不处理。
if (a.length<2) return;
int lo=0;
int hi=a.length-1;
//初始数组有2个或以上元素时入栈
ArrayFromTo subArray=new ArrayFromTo();
subArray.lo=lo;
subArray.hi=hi;
s.push(subArray);
while(!s.isEmpty())
{
//取出栈顶数组
subArray=s.pop();
//切分成左右子数组
int j=partition(a,subArray.lo,subArray.hi);
int leftLength=j-subArray.lo;
int rightLength=subArray.hi-j;
//将左右子数组中长度大1的数组入栈,先将长数组入栈,后将短数组入栈
if(leftLength>1 && leftLength>rightLength)
{
ArrayFromTo subArrayLeft=new ArrayFromTo();
subArrayLeft.lo=subArray.lo;
subArrayLeft.hi=j-1;
s.push(subArrayLeft);
//
if(rightLength>1)
{
ArrayFromTo subArrayRight=new ArrayFromTo();
subArrayRight.lo=j+1;
subArrayRight.hi=subArray.hi;
s.push(subArrayRight);
}
}
else if(rightLength>1 && leftLength<rightLength)
{
ArrayFromTo subArrayRight=new ArrayFromTo();
subArrayRight.lo=j+1;
subArrayRight.hi=subArray.hi;
s.push(subArrayRight);
//
if(leftLength>1)
{
ArrayFromTo subArrayLeft=new ArrayFromTo();
subArrayLeft.lo=subArray.lo;
subArrayLeft.hi=j-1;
s.push(subArrayLeft);
}
}
}
}
private int partition(Comparable[] a,int lo,int hi)
{
int i=lo,j=hi+1;
Comparable v=a[lo];
while(true)
{
while(less(a[++i],v)) if(i==hi) break;
while(less(v,a[--j])) if(j==lo) break;
if(i>=j) break;
exch(a,i,j);
}
exch(a,lo,j);
return j;
}
private boolean less(Comparable v,Comparable w)
{ return v.compareTo(w)<0;}
private void exch(Comparable[] a,int i,int j)
{
Comparable t=a[i];
a[i]=a[j];
a[j]=t;
}
private void show(Comparable[] a)
{
for (int i=0;i<a.length;i++)
StdOut.print(a[i]+" ");
StdOut.println();
}
public boolean isSorted(Comparable[] a)
{
for (int i=1;i<a.length;i++)
if(less(a[i],a[i-1])) return false;
return true;
}
public static void main(String[] args)
{
int N=Integer.parseInt(args[0]);
Double[] a=new Double[N];
for(int k=0;k<N;k++)
a[k]=StdRandom.random();
E2d3d20 QuickSortOfWhile=new E2d3d20();
QuickSortOfWhile.sort(a);
assert QuickSortOfWhile.isSorted(a);
QuickSortOfWhile.show(a);
}
}
--栈
import java.util.Iterator;
public class Stack<Item> implements Iterable<Item>
{
private Node first;
private int N;
private class Node
{
Item item;
Node next;
}
public boolean isEmpty() {return first==null;}
public int size(){return N;}
public void push(Item item)
{
Node oldfirst=first;
first=new Node();
first.item=item;
first.next=oldfirst;
N++;
}
public Item pop()
{
Item item=first.item;
first=first.next;
N--;
return item;
}
public Iterator<Item> iterator()
{return new ListIterator();}
private class ListIterator implements Iterator<Item>
{
private Node current=first;
public boolean hasNext()
{return current !=null;}
public void remove(){}
public Item next()
{
Item item=current.item;
current=current.next;
return item;
}
}
public static void main(String[] args)
{
Stack<String> s=new Stack<String>();
while(!StdIn.isEmpty())
{
String item=StdIn.readString();
if(!item.equals("-"))
s.push(item);
else if(!s.isEmpty()) StdOut.print(s.pop()+ " ");
}
StdOut.println("(" +s.size() + " left on stack)");
}
}
public class E2d3d20
{
//一个用记录子数组开始与结束索引的类
private class ArrayFromTo
{
int lo;
int hi;
}
//一个用来记录所子数组的栈
private Stack<ArrayFromTo> s=new Stack<ArrayFromTo>();
public void sort(Comparable[] a)
{
StdRandom.shuffle(a);
//初始数组只有0个或1个元素时不处理。
if (a.length<2) return;
int lo=0;
int hi=a.length-1;
//初始数组有2个或以上元素时入栈
ArrayFromTo subArray=new ArrayFromTo();
subArray.lo=lo;
subArray.hi=hi;
s.push(subArray);
while(!s.isEmpty())
{
//取出栈顶数组
subArray=s.pop();
//切分成左右子数组
int j=partition(a,subArray.lo,subArray.hi);
int leftLength=j-subArray.lo;
int rightLength=subArray.hi-j;
//将左右子数组中长度大1的数组入栈,先将长数组入栈,后将短数组入栈
if(leftLength>1 && leftLength>rightLength)
{
ArrayFromTo subArrayLeft=new ArrayFromTo();
subArrayLeft.lo=subArray.lo;
subArrayLeft.hi=j-1;
s.push(subArrayLeft);
//
if(rightLength>1)
{
ArrayFromTo subArrayRight=new ArrayFromTo();
subArrayRight.lo=j+1;
subArrayRight.hi=subArray.hi;
s.push(subArrayRight);
}
}
else if(rightLength>1 && leftLength<rightLength)
{
ArrayFromTo subArrayRight=new ArrayFromTo();
subArrayRight.lo=j+1;
subArrayRight.hi=subArray.hi;
s.push(subArrayRight);
//
if(leftLength>1)
{
ArrayFromTo subArrayLeft=new ArrayFromTo();
subArrayLeft.lo=subArray.lo;
subArrayLeft.hi=j-1;
s.push(subArrayLeft);
}
}
}
}
private int partition(Comparable[] a,int lo,int hi)
{
int i=lo,j=hi+1;
Comparable v=a[lo];
while(true)
{
while(less(a[++i],v)) if(i==hi) break;
while(less(v,a[--j])) if(j==lo) break;
if(i>=j) break;
exch(a,i,j);
}
exch(a,lo,j);
return j;
}
private boolean less(Comparable v,Comparable w)
{ return v.compareTo(w)<0;}
private void exch(Comparable[] a,int i,int j)
{
Comparable t=a[i];
a[i]=a[j];
a[j]=t;
}
private void show(Comparable[] a)
{
for (int i=0;i<a.length;i++)
StdOut.print(a[i]+" ");
StdOut.println();
}
public boolean isSorted(Comparable[] a)
{
for (int i=1;i<a.length;i++)
if(less(a[i],a[i-1])) return false;
return true;
}
public static void main(String[] args)
{
int N=Integer.parseInt(args[0]);
Double[] a=new Double[N];
for(int k=0;k<N;k++)
a[k]=StdRandom.random();
E2d3d20 QuickSortOfWhile=new E2d3d20();
QuickSortOfWhile.sort(a);
assert QuickSortOfWhile.isSorted(a);
QuickSortOfWhile.show(a);
}
}
--栈
import java.util.Iterator;
public class Stack<Item> implements Iterable<Item>
{
private Node first;
private int N;
private class Node
{
Item item;
Node next;
}
public boolean isEmpty() {return first==null;}
public int size(){return N;}
public void push(Item item)
{
Node oldfirst=first;
first=new Node();
first.item=item;
first.next=oldfirst;
N++;
}
public Item pop()
{
Item item=first.item;
first=first.next;
N--;
return item;
}
public Iterator<Item> iterator()
{return new ListIterator();}
private class ListIterator implements Iterator<Item>
{
private Node current=first;
public boolean hasNext()
{return current !=null;}
public void remove(){}
public Item next()
{
Item item=current.item;
current=current.next;
return item;
}
}
public static void main(String[] args)
{
Stack<String> s=new Stack<String>();
while(!StdIn.isEmpty())
{
String item=StdIn.readString();
if(!item.equals("-"))
s.push(item);
else if(!s.isEmpty()) StdOut.print(s.pop()+ " ");
}
StdOut.println("(" +s.size() + " left on stack)");
}
}