Java快速排序的实现方法示例

 更新时间:2024年03月07日 10:40:30   作者:大家都说我身材好  
快速排序是对冒泡排序的一种改进,下面这篇文章主要给大家介绍了关于Java快速排序的实现方法,文中通过代码介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下

前言

快速排序是一种常用的基于比较的排序算法,其时间复杂度为 O(nlogn),并且具有稳定性和广泛的应用场景。本文将全面详细的讲解一下 Java 中快速排序算法的原理、实现以及时间复杂度等问题。

一、快速排序的原理

快速排序是一种分治思想的排序算法,其基本原理可以概括为以下三步:

  • 选取一个基准元素,将待排序数组划分为左右两个子数组;

  • 将比基准元素小的数都移到左子数组中,将比基准元素大的数都移到右子数组中;

  • 对左右两个子数组递归执行上述操作,直到每个子数组只剩下一个元素为止。

具体来说,快速排序的过程如下:

  • 首先选取待排序数组中一个元素作为基准元素,通常选择第一个元素或最后一个元素作为基准元素。

  • 遍历数组,将小于基准元素的元素放到左边,大于等于基准元素的元素放到右边,此时数组被划分成了两个部分。

  • 对左半部分和右半部分分别递归执行上述操作,直到排序完成。

需要注意的是,在遍历数组时,一般采用双指针法来实现。具体来说,我们使用一个左指针指向数组的第一个元素,用一个右指针指向数组的最后一个元素,然后从左到右依次遍历数组中的元素,如果当前元素小于基准元素,就将它和左指针所指的元素交换,然后将左指针向右移动一位;如果当前元素大于等于基准元素,就将它和右指针所指的元素交换,然后将右指针向左移动一位。重复上述操作直到左指针和右指针相遇为止。

二、快速排序的实现

在 Java 中,我们可以使用以下代码来实现快速排序算法:

public static void quickSort(int[] arr, int left, int right) {
    if (left < right) { // 当数组只有一个元素时结束递归
        int partitionIndex = partition(arr, left, right); // 对数组进行划分,获取基准元素位置
        quickSort(arr, left, partitionIndex - 1); // 对左子数组递归执行快速排序
        quickSort(arr, partitionIndex + 1, right); // 对右子数组递归执行快速排序
    }
}

public static int partition(int[] arr, int left, int right) {
    int pivot = arr[left]; // 将数组的第一个元素设置为基准元素
    int i = left; // 初始化左指针
    int j = right; // 初始化右指针
    while (i < j) { // 当左指针和右指针没有相遇时循环
        while (i < j && arr[j] >= pivot) { // 右指针从右向左遍历,找到第一个小于基准元素的元素
            j--;
        }
        if (i < j) { // 如果左指针和右指针没有相遇,将右指针所指的元素赋值给左指针所指的位置
            arr[i] = arr[j];
            i++;
        }
        while (i < j && arr[i] < pivot) { // 左指针从左向右遍历,找到第一个大于等于基准元素的元素
            i++;
        }
        if (i < j) { // 如果左指针和右指针没有相遇,将左指针所指的元素赋值给右指针所指的位置
            arr[j] = arr[i];
            j--;
        }
    }
    arr[i] = pivot; // 将基准元素放到最终位置
    return i; // 返回基准元素的位置
}

在上述代码中,quickSort() 方法是快速排序算法的入口,它采用递归的方式对左右两个子数组进行排序。partition() 方法则是用来对数组进行划分的,它使用双指针法来实现。

具体来说,我们首先将数组的第一个元素作为基准元素 pivot,然后初始化左指针 i 和右指针 j。接着,我们先让右指针 j 从右向左遍历数组,找到第一个小于基准元素的元素,并将其赋值给左指针所指的位置;然后让左指针 i 从左向右遍历数组,找到第一个大于等于基准元素的元素,并将其赋值给右指针所指的位置。重复上述操作直到左指针和右指针相遇。

最后,将基准元素 pivot 放到最终位置,即左指针所指的位置,这样就完成了对数组的一次划分。在 partition() 方法中,返回的是基准元素的位置,这个位置将用于快速排序算法的递归操作。

三、快速排序的时间复杂度

快速排序算法的时间复杂度主要取决于对数组进行划分的过程。在最坏情况下,如果每次划分都只能规模减少 1,那么快速排序的时间复杂度为 O(n^2),这种情况发生在数组已经排好序或基本排好序的情况下。

在平均情况下,假设每次划分可以将数组分成大小分别为 k 和 (n-k-1) 的两个子数组,那么快速排序的时间复杂度为 O(nlogn)。这是因为快速排序算法的递归深度为 logn,每一层的比较次数为 n,因此总体比较次数为 nlogn。

需要注意的是,快速排序算法的时间复杂度并不稳定,因为基准元素的选择对算法的效率有很大的影响。如果每次都选取最大或最小的元素作为基准元素,那么算法的时间复杂度将退化到 O(n^2)。因此,在实际应用中,我们通常会采用一些优化技巧来提高快速排序算法的效率,如随机选择基准元素、三数取中法等。

补充:快速排序的另一种实现

我认为这种写法更容易理解

public static void QuickSort(int []arr,int low,int high) {
		if(low<high) {
			int pivotpos=partition(arr,low,high);
			QuickSort(arr,low,pivotpos-1);
			QuickSort(arr,pivotpos+1,high);
		}
	}
 
	private static int partition(int[] arr, int low, int high) {
		 int pivot=arr[low];
		 while(low<high) {
			 //起初,一定要从右边指针开始,因为arr[low]的值已经扔给了pivot,arr[low]
			 //想象成无数字的空位
			 while(low<high&&pivot<=arr[high]) {
				 --high;
			 }
			 
			 //把比pivot的小的数扔到左边指针
			 //把arr[high]扔到arr[low]这个空位上
			 //然后,high位置可以想象成无数字的空位
			 arr[low]=arr[high];
			 
			 while(low<high&&arr[low]<=pivot) {
				 ++low;
			 }
			 //把比pivot大的数扔到右边
			//把arr[low]扔到arr[high]这个空位上
			//然后,low位置可以想象成是无数字的空位
			 arr[high]=arr[low];
		 }
		 //此时low==high,return high也一样
		 arr[low]=pivot;
		return low;
	}
}

总结

到此这篇关于Java快速排序实现方法的文章就介绍到这了,更多相关Java快速排序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mybatis-plus @select动态查询方式

    mybatis-plus @select动态查询方式

    这篇文章主要介绍了mybatis-plus @select动态查询方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • Spring Boot的Controller控制层和页面

    Spring Boot的Controller控制层和页面

    这篇文章主要介绍了Spring Boot的Controller控制层和页面,需要的朋友可以参考下
    2017-04-04
  • Java Swing中JTable渲染器与编辑器用法示例

    Java Swing中JTable渲染器与编辑器用法示例

    这篇文章主要介绍了Java Swing中JTable渲染器与编辑器用法,结合实例形式较为详细的分析了Swing中JTable渲染器与编辑器的功能、使用方法及相关注意事项,需要的朋友可以参考下
    2017-11-11
  • Spring实现HikariCP连接池的示例代码

    Spring实现HikariCP连接池的示例代码

    在SpringBoot 2.0中,我们使用默认连接池是HikariCP,本文讲一下HikariCP的具体使用,具有一定的参考价值,感兴趣的可以了解一下
    2021-08-08
  • 浅谈Java8对字符串连接的改进正确姿势

    浅谈Java8对字符串连接的改进正确姿势

    这篇文章主要介绍了Java8:对字符串连接的改进,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • SpringBoot实现API接口的完整代码

    SpringBoot实现API接口的完整代码

    这篇文章主要给大家介绍了关于SpringBoot实现API接口的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • Spring Boot创建可执行jar包的实例教程

    Spring Boot创建可执行jar包的实例教程

    这篇文章主要介绍了Spring Boot创建可执行jar包的实例教程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • 基于Java编写简单的Excel工具类

    基于Java编写简单的Excel工具类

    这篇文章主要为大家详细介绍了如何基于Java编写简单的Excel工具类,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考下
    2024-02-02
  • 基于Springboot使用logback的注意事项

    基于Springboot使用logback的注意事项

    这篇文章主要介绍了Springboot使用logback的注意事项,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Java程序包装成桌面应用程序方式

    Java程序包装成桌面应用程序方式

    这篇文章主要介绍了Java程序包装成桌面应用程序方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01

最新评论