荷兰国旗问题和快速排序

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;
    }
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值