快速排序的两种方式,递归和非递归,非递归使用栈
python写法
def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quicksort(left) + middle + quicksort(right)
scala更简洁
def sort(in:List[Int]):List[Int]={
if (in.length<2)in else sort(in.filter { _<in.head })++in.filter { _==in.head }++sort(in.filter { _>in.head })
}
Java递归写法
public class QuickSort {
//排序
public void quickSort(int A[],int p,int r)
{
if (p<r) {
int q=randomPartition(A, p, r);
//System.out.println(q);
quickSort(A, p, q-1);
quickSort(A, q+1, r);
}
}
public int randomPartition(int A[],int p,int r)
{//选择随机数是一个坑爹的存在,还不如直接选定x=A[r]效率高
// int i= (int) (Math.random()*(r - p)+p);
// int tmp=A[r];
// A[r]=A[i];
// A[i]=tmp;
return partition(A, p, r);
}
//划分
public int partition(int A[],int p,int r)
{
int x=A[r];
int i=p-1;
int tmp=0;
for (int j = p; j < r; j++) {
if (A[j]<=x) {
i=i+1;
tmp=A[i];
A[i]=A[j];
A[j]=tmp;
}
}
tmp=A[i+1];
A[i+1]=A[r];
A[r]=tmp;
return i+1;
}
public int[] randomArray(int n)
{
int A[]=new int[n];
for (int i = 0; i < n; i++) {
A[i]=(int) (Math.random()*100000);
}
return A;
}
public static void main(String[] args) {
QuickSort quickSort=new QuickSort();
int A[]=quickSort.randomArray(50000);
long startTime=System.nanoTime();
quickSort.quickSort(A, 0, A.length-1);
long endTime=System.nanoTime();
System.out.println(endTime-startTime);
// for(int i:A)
// {
// System.out.println(i);
// }
}
}
Java非递归写法
import java.util.Stack;
//快速排序的非递归实现,利用系统的栈stack
public class QuickSortNonRecursion {
public static void main(String[] args) {
QuickSortNonRecursion qsnr = new QuickSortNonRecursion();
int[] array = {0, 2, 11, 121, 18, 99, 3, 5, 101, 22, 9, 100};
qsnr.quicksort(array);
for (int i : array) {
System.out.print(i + " ");
}
}
public void quicksort(int[] array) {
if (array == null || array.length == 1) return;
//存放开始与结束索引
Stack<Integer> s = new Stack<Integer>();
//压栈
s.push(0);
s.push(array.length - 1);
//利用循环里实现
while (!s.empty()) {
int right = s.pop();
int left = s.pop();
//如果最大索引小于等于左边索引,说明结束了
if (right <= left) continue;
int i = partition(array, left, right);
if (left < i - 1) {
s.push(left);
s.push(i - 1);
}
if (i + 1 < right) {
s.push(i+1);
s.push(right);
}
}
}
//找到轴心,进行交换
public int partition (int[] data, int first, int end)
{
int temp;
int i=first,j=end;
if(first<end)
{
temp=data[i];
//当i=j的时候,则说明扫描完成了
while(i<j)
{
//从右边向左边扫描找到一个小于temp的元素
while(j>i&&data[j]>temp)j--;
if(i<j)
{
//将该元素赋值给temp
data[i]=data[j];
//赋值后就应该将i+1指向下一个序号
i++;
}
//然后从左边向右边开始扫描,找到一个大于temp的元素
while(i<j&&temp>data[i])i++;
if(i<j)
{
//将该元素赋值给temp
data[j]=data[i];
//赋值后就应该将j-1指向前一个序号
j--;
}
}
//将轴数据放在i位置中
data[i]=temp;
}
return i;
}
}