算法java快速排序的两种方法(单边循环、双边循环)

简介: 算法java快速排序的两种方法(单边循环、双边循环)

算法java快速排序的两种方法(单边循环、双边循环)


快速排序

1、平均时间复杂度是nlog2n,最坏时间复杂度n2

2、数据量较大时,优势非常明显

3、属于不稳定排序

快速排序的两种方法(单边循环、双边循环)

1、单边循环

package cn.itcast.algorithm.suanFa;
/**
 * 快速排序____单边循环
 */
import java.util.Arrays;
public class MainS15 {
    public static void main(String[] args) {
        int[] a = {5, 3, 7, 2, 9, 8, 1, 4};
        quick(a, 0, a.length -1);
    }
    //对quick进行递归
    private static void quick(int[] a, int l, int h){
        if (l >= h){ //区间里面只有一个或者没有元素的时候停止
            return;
        }
        int p = partition(a, l, h);
        quick(a, l, p-1);//左边分区的范围确定
        quick(a, p+1, h);//右边分区的范围确定
    }
    private static int partition(int[] a, int l, int h) {
        int pv = a[h];//选择最右元素作为基准点元素
        int i = l;
        for (int j = l;j < h;j++){  //j指针负责找到比基准点小的元素,找到则与i进行交换
            if (a[j] < pv){
                if (i != j) {
                    swap(a, i, j);
                }
                i++;
            }
        }
        if (i != h) {
            swap(a, h, i);   //最后基准点与i进行交换,i即为分区位置
        }
        System.out.println(Arrays.toString(a)+" i = " + i);
        //返回值代表了基准点元素所在的正确索引,用它确定下一轮分区的边界
        return i;
    }
    private static void swap(int[] a, int s, int i) {
        int temp = a[s];
        a[s] = a[i];
        a[i] = temp;
    }
}

2、双边循环

package cn.itcast.algorithm.suanFa;
import java.util.Arrays;
/**
 * 快速排序____双边循环
 */
public class MainS16 {
    public static void main(String[] args) {
        int[] a = {5, 3, 7, 2, 9, 8, 1, 4};
        System.out.println(Arrays.toString(a));
        quick(a, 0, a.length -1);
    }
    //对quick进行递归
    private static void quick(int[] a, int l, int h){
        if (l >= h){ //区间里面只有一个或者没有元素的时候停止
            return;
        }
        int p = partition(a, l, h);
        quick(a, l, p-1);//左边分区的范围确定
        quick(a, p+1, h);//右边分区的范围确定
    }
    private static int partition(int[] a, int l, int h) {
        int pv = a[l];//选择最左元素作为基准点元素,必须先j后i的查找
        int i = l;
        int j = h;
        while(i < j){
            //j 从右找小的
            //j 指针负责从右向左找比基准点小的元素
            while(i < j && a[j] > pv){
                j--;
            }
            //i 从左找大的
            //i 指针负责从左向右找比基准点大的元素
            while(i < j && a[j] <= pv){
                i++;
            }
            //找到之后二者交换,直至i,j相交,循环停止
            swap(a, i, j);
        }
        swap(a, l, j);
        System.out.println(Arrays.toString(a)+" j = " + j);
        return j;
    }
    private static void swap(int[] a, int s, int i) {
        int temp = a[s];
        a[s] = a[i];
        a[i] = temp;
    }
}
相关文章
|
7天前
|
搜索推荐 C语言
【排序算法】快速排序升级版--三路快排详解 + 实现(c语言)
本文介绍了快速排序的升级版——三路快排。传统快速排序在处理大量相同元素时效率较低,而三路快排通过将数组分为三部分(小于、等于、大于基准值)来优化这一问题。文章详细讲解了三路快排的实现步骤,并提供了完整的代码示例。
28 4
|
6天前
|
Java 程序员 API
Java循环操作哪个快?
本文探讨了Java中Stream API与传统for循环的性能对比及适用场景。作者通过实际案例分析,指出在某些情况下,过度使用Stream API会导致代码可读性和维护性下降。测试结果显示,在数据量较小的情况下,普通for循环的性能优于Stream API,尤其是在涉及多次类似操作时。因此,建议在开发中根据具体需求选择合适的遍历方式,以提高代码的可读性和性能。
Java循环操作哪个快?
|
10天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
50 4
|
21天前
|
Java API
Java 对象释放与 finalize 方法
关于 Java 对象释放的疑惑解答,以及 finalize 方法的相关知识。
42 17
|
14天前
|
Java 测试技术 Maven
Java一分钟之-PowerMock:静态方法与私有方法测试
通过本文的详细介绍,您可以使用PowerMock轻松地测试Java代码中的静态方法和私有方法。PowerMock通过扩展Mockito,提供了强大的功能,帮助开发者在复杂的测试场景中保持高效和准确的单元测试。希望本文对您的Java单元测试有所帮助。
28 2
|
21天前
|
算法 Java 测试技术
🧑‍💻Java零基础:Java 的循环退出语句 break
【10月更文挑战第16天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
36 6
|
22天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
16 3
|
22天前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
15 2
|
22天前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
15 1
|
22天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
28 1