十大排序算法之快速排序(两种方法)

十大排序算法之快速排序

本文采用Java书写选择排序,其他语言类似可以借鉴着写
  • 思想:在待排序序列中选择一个分割元素,将待排序序列中所有比分割元素关键字小的元素移动到分割元素左侧位置;将待排序序列中所有比分割元素关键字大的元素移动到分割元素左侧位置;等于的放在相邻位置,然后对大于分割元素的部分看做一个待排序的子序列,小于分割元素的部分看做另外一个待排序的子序列,重复执行,直到全部完全有序。
  • 效果图:
    请添加图片描述
    请添加图片描述

算法的复杂度和稳定性

  • 稳定性:
    不稳定,相同两个元素可能发生值得交换
  • 复杂度:
    时间复杂度:O(NlogN)(最好和平均都是), 最差是O(N^2)
    空间复杂度:O(logN)

代码实现

下面是两种快排,当然思路大致相同

0X1

这一种的思路是将每一个序列最右边数字设置为标志位,从最左边依次遍历,小于的放在序列左边,大于的放在序列右边,等于放中间。然后将最右边的数字,与中间的最右边的一个数字进行互换。返回临界点中间的左右两个下标,再对两边看成子序列递归进行

package Sort;

/**
 * @Description:
 * @ProjectNmae: gitTest
 * @PackageName: Sort
 * @ClassName: QuickSort
 * @Author: Y-peak
 * @Date: 2021.08.29 15:25   星期日
 */

public class QuickSort {
    public static void quickSort(int[] arr){
        if(arr == null || arr.length < 2){
            return;
        }
        quickSort(arr, 0, arr.length-1);
    }
    public static void quickSort(int[] arr, int L, int R){
        if(L < R){
            swap(arr,L+(int)(Math.random()*(R-L+1)),R);  //为了达到随机选择的目的使得复杂度变为O(NlogN)
            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 less = L - 1;
        int more = R;
        while(L < more){
            if (arr[L] < arr[R]) {
                swap(arr, ++less, L++);
            }else if(arr[L] > arr[R]){
                swap(arr, --more, L);
            }else {
                L++;
            }
        }
        swap(arr, more, R);
        return new int[]{less+1, more};
    }

    public static void swap(int[] arr, int i, int j){
        int temp;
        temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] arr = new int[]{3,2,4,1,8,7,9};
        quickSort(arr);
        for(int i :arr){
            System.out.println(i);
        }
    }
}

0X2

这一种的思路是将每一个序列最左边数字设置为标志位,然后分别从左右两边开始遍历,找到左边第一个大于标志位的,和右边第一个小于标志位的进行互换,接着找第二个,第三个,.....直到左右两边共同遍历完整个序列。 这里是共同不是分别 然后,交换最左边的标志位和遍历重合的位置,返回中间位置作为子序列遍历的临界点, 再对两边看成子序列递归进行 与第一种的区别的,无法一次性将相同的集中在中间。

package Sort;

/**
 * @Description:
 * @ProjectNmae: gitTest
 * @PackageName: Sort
 * @ClassName: QuickSort
 * @Author: Y-peak
 * @Date: 2021.08.29 15:25   星期日
 */

public class QuickSort {
    public static void quickSort(int[] arr){
        if(arr == null || arr.length < 2){
            return;
        }
        quickSort(arr, 0, arr.length-1);
    }
    public static void quickSort(int[] arr, int L, int R){
        int mid;
        if(L < R){
            //swap(arr,L+(int)(Math.random()*(R-L+1)),L);
            mid = partition(arr,L,R);
            quickSort(arr, L, mid - 1);
            quickSort(arr,mid + 1, R);

        }
    }

    public static int partition(int[] arr, int L,int R){
        int left = L;
        int right = R + 1;
        while(left<right){
            do left++; while (left<=R && arr[left] < arr[L]);
            do right--; while (arr[right] > arr[L]);
            if (left<right)
                swap(arr,left,right);
        }
        swap(arr, L, right);
        return right;
    }

    public static void swap(int[] arr, int i, int j){
        int temp;
        temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] arr = new int[]{3,2,4,1,8,7,9};
        quickSort(arr);
        for(int i :arr){
            System.out.println(i);
        }
    }
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值