荷蘭國旗問題和快速排序
阿新 • • 發佈:2019-02-13
1、 題目一:
給定一個數組arr和一個數num,讓大於這數的數字放在陣列的右邊,小於等於這個數字放在陣列的左邊。 要求:時間複雜度O(n),額外空間複雜度O(1)
/*我的程式碼*/
public class exercise__1 {
public static void sort_num(int[] arr,int num){
int left_sub=0;
int right_sub=arr.length-1;
for (int i = 0; i<arr.length; i++) {
if (arr[left_sub] <=num) {
left_sub=left_sub+1 ;
continue;
}
if(arr[right_sub]>num){
right_sub=right_sub-1;
continue;
}
swap(arr,left_sub,right_sub);
left_sub=left_sub+1;
right_sub=right_sub-1;
if (left_sub==right_sub){
break ;
}
}
}
public static void swap(int[] arr,int left,int right){
int station=arr[left];
arr[left]=arr[right];
arr[right]=station;
}
public static void main(String[] args) {
int[]arr={1,50,20,67,69,82,11,3,59,70,3,4,2,1,1,0};
sort_num(arr,50 );
for (int i = 0; i < arr.length-1; i++) {
System.out.println(arr[i]);
}
}
}
code2
/*演算法*/
class niu_sortnum{
public static void sortnum(int[] arr,int num){
int small_index=-1;
for (int i = 0; i <arr.length ; i++) {
if (arr[i]<=num){
swap(arr,++small_index,i);
}
}
}
public static void swap(int[] arr,int left,int right){
int station=arr[left];
arr[left]=arr[right];
arr[right]=station;
}
public static void main(String[] args) {
int[] arr={1,4,5,7,9,10,100,300,400,500,1000,1,2,4,7,123,300,1,9};
sortnum(arr,100);
for (int i=0;i<arr.length-1;i++){
System.out.println(arr[i]);
}
}
2、題目二:(荷蘭國旗問題)
給定一個數組arr,和一個數num,請把小於num的數放在陣列的左邊,等於num的書放在中間,大於num的數放在右邊。 要求:時間複雜度O(n),額外空間複雜度O(1)
class exercise2{
// small、big分別指向陣列的最-1和arr.length的下標,使用current變數作為遍歷陣列的下標
// 如果arr[cuurrent]<num;交換swap(arr[++small],arr[curent]),small右移動一位,current++
// 如果arr[cuurrent]==num;不做任何處理,current++繼續向右遍歷
// 如果arr[cuurrent]>num;交換swap(arr[--big],arr[curent]),big左移動一位,current不移動,
//迴圈終止條件current==big
public static void sortnum(int[] arr,int num){
int small=-1;
int big=arr.length;
int current=0;
while(current!=big) {
if (arr[current]<num){
swap(arr,++small,current++);
}
else if (arr[current]==num){
current++;
}
else if(arr[current]>num){
swap(arr,--big,current);
}
}
}
public static void swap(int[] arr,int left,int right){
int station=arr[left];
arr[left]=arr[right];
arr[right]=station;
}
public static void main(String[] args) {
int[] arr={1,3,50,500,9,0,60,70,50,51,81,1,5,8,100};
sortnum(arr,50);
for (int i = 0; i <arr.length ; i++) {
System.out.println(arr[i]);
}
}
}
3、經典快速排序
快速排序(經典快排)
import java.util.Arrays;
/*
快速排序(經典快排)
·選取第一個數(或最後一個數)作為基準,把它放在陣列的中,陣列一分為二,左邊的數比它小右邊的數比它大
·將左邊的部分遞迴
·將右邊的部分遞迴
*/
public class quickSort {
public static void QuickSort(int[] A,int p,int r){//p,r分別為陣列的首元素和尾元素下標
if (p<r){
int q=Partition(A,p,r);//劃分陣列,找到首元素A[p]在排好序後的位置q
swap(A,p,q);
QuickSort(A,p,q-1);
QuickSort(A,q+1,r);
}
}
public static void swap(int[] arr,int a,int b){
int tem=arr[a];
arr[a]=arr[b];
arr[b]=tem;
}
public static int Partition(int []A,int p,int r){
/*
輸入:陣列A[p,r];
輸出:j,,A的首元素在排好序的陣列中的位置
*/
int key=A[p];
int i=p;
int j=r;
while (i<j){
/*從左向右遍歷*/
while (A[i]<=key){
i=i+1;
}
/*從右向左遍歷*/
while(A[j]>key){
j=j-1;
}
if (i<j){
swap(A,i,j);
}
}
return j;
}
public static void main(String[] args) {
int[] arr= {27, 99, 30, 1, 0, 9, 38, 57, 90, 1, 27, 30, 8};
System.out.println(Arrays.toString(arr));
QuickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
}
4、隨機快排
import java.util.Arrays;
public class random_quicksort {
public static void quickSort(int []arr,int L,int R){
if (L<R){
/*
Math.random返回>=0,小於R-L+1的數
*/
swap(arr, L+(int) Math.random()*(R-L+1),R);
int[]p=partition(arr,L,R);
quickSort(arr,L,p[0]-1);
quickSort(arr,p[1]+1,R);
}
}
public static int[] partition(int[] arr, int L, int R){
int small=L-1;
int big=R;
int key=arr[R];
int current=L;
while(current<big) {
if (arr[current]<key){
swap(arr,++small,current++);
}
else if(arr[current]>key){
swap(arr,--big,current);
}
else{
current++;
}
}
swap(arr,R,big);
return new int[]{small+1,big};
}
public static void swap(int[] arr,int a,int b){
int station=arr[a];
arr[a]=arr[b];
arr[b]=station;
}
public static void main(String[] args) {
int[] arr={40,3,50,500,9,0,60,70,50,51,81,1,5,8,100};
System.out.println(Arrays.toString(arr));
quickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
}
5、根據荷蘭國旗改進後的快排
import java.util.Arrays;
public class quickSort_modify {
public static void quickSort(int []arr,int L,int R){
if (L<R){
int[]p=partition(arr,L,R);
quickSort(arr,L,p[0]-1);
quickSort(arr,p[1]+1,R);
}
}
public static int[] partition(int[] arr, int L, int R){
int small=L-1;
int big=R;
int key=arr[R];
int current=L;
while(current<big) {
if (arr[current]<key){
swap(arr,++small,current++);
}
else if(arr[current]>key){
swap(arr,--big,current);
}
else{
current++;
}
}
swap(arr,R,big);
return new int[]{small+1,big};
}
public static void swap(int[] arr,int a,int b){
int station=arr[a];
arr[a]=arr[b];
arr[b]=station;
}
public static void main(String[] args) {
int[] arr={40,3,50,500,9,0,60,70,50,51,81,1,5,8,100};
System.out.println(Arrays.toString(arr));
quickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
}
6、快排的非遞迴實現
import java.util.Stack;
public class not_recursion_quicksort {
public static void main(String[] args) {
int[] array = { 3, 2, 11, 121,2,32,545,3434,222,18, 99, 233, 53, 101, 22, 9, 100 };
// partition(array,0,array.length-1);
not_recursion_quicksort.sort(array);
for (int num:array) {
System.out.print(num + " ");
}
}
public static void sort(int[] array) {
if (array == null || array.length == 1)
return;
//棧頂的兩個元素存放要partition的最左座標和最右座標
Stack<Integer> s = new Stack<Integer>();
//初始化最左和最右座標,即0和len-1
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);
//右半部分入棧
s.push(i+1);
s.push(right);
//左半部分入棧
s.push(left);
s.push(i-1);
}
}
//將pivot放到最終位置,並且左邊的元素都小於等於pivot,右邊的元素都大於等於pivot
public static int partition(int[] a, int left, int right){
int i = left,j=right;
int pivot = a[right]; //將pivot暫存,因為之後這個位置將由比pivot小的數佔據
while(i!=j){
for(;i<j && a[i]<=pivot;i++); //從左邊找一個比pivot大的數
a[j] = a[i]; //將這個數放到右邊空位
for(;i<j && a[j]>=pivot;j--); //從右邊找一個比pivot小的數
a[i] = a[j]; //將這個數放到左邊空位,空位是由pivot或之前比pivot大的數留出來的
}
a[i] = pivot;
return i;
}
}