剑指offer——快速排序
时间:2022-05-03
本文章向大家介绍剑指offer——快速排序,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
快速排序是目前所有排序中性能较好的一种算法,最好情况和平均情况下时间复杂度均为O(nlogn),最坏的情况下时间复杂度为O(n^2)。快速排序采用递归,用空间换取时间。由于使用了递归,因此需要额外的存储空间。
快速排序由三个函数构成,分别为QuickSort(int[] arr)、QuickSort(int[] arr,int start,int end)、partition(int[] arr,int start,int end)。其中partition函数能够从当前待排序序列中找出一个主元,并使得主元左侧的元素均小于主元,主元右侧的元素均大于主元。Partition函数完成对待排序序列的分割后,交给QuickSort(int[] arr,int start,int end)处理,QuickSort分别将被Partition分隔的两个子序列进行快速排序。QuickSort(int[] arr)是整个快速排序的入口函数,用户只需传入待排序数组即可。
下面为java实现的快速排序,若有bug欢迎拍版
/**
* 实现快速排序
* @author chibozhou
*/
public class QuickSort {
/**
* 本函数实现一趟快速排序,以数组的第一个元素为主元,
* 本函数运行结束后使得主元左侧的元素小于主元,主元右侧的元素大于主元。
* @param arr 待排序的数组
* @return 返回经一趟排序后主元的下标
*/
private static int partition(int[] arr,int start,int end){
//健壮性判断
if(arr.length<=0){
System.out.println("数组为空!");
return -1;
}
if(start<0 || end<0 || start>end){
System.out.println("start、end非法!");
return -1;
}
//i指向数组头、j指向数组尾
int i=start+1,j=end;
//选择数组第一位为主元
int key = arr[start];
//若i与j未相遇,则执行以下循环
while(i<j){
//i从左向右扫描,直到当前元素大于主元时停下
while(arr[i]<=key && i<end){
i++;
}
//j从右向左扫描,直到当前元素小于主元时停下
while(arr[j]>=key && j>start){
j--;
}
//i、j停下有两种情况:1.
if(i<j)
swap(arr,i,j);
}
//将主元与j交换
swap(arr,start,j);
System.out.println("某一趟排序结果:"+printArray(arr));
//返回新的主元下标
return j;
}
/**
* 快速排序入口函数
* @param arr 待排序数组
* @return 返回有序的数组
*/
public static void QuickSort(int[] arr){
//健壮性判断
if(arr==null || arr.length<=0){
System.out.println("数组为空!");
return;
}
//通过递归进行快速排序
QuickSort(arr,0,arr.length-1);
}
/**
* 快速排序的递归函数
* @param arr 待排序数组
* @param start 数组的起始下标
* @param end 数组的结束下标
* @return 返回当前有序子序列
*/
private static void QuickSort(int[] arr,int start,int end){
if(start<end){
//获取主元
int key = partition(arr,start,end);
//对主元左侧的序列进行快速排序
QuickSort(arr,start,key-1);
//对主元右侧的序列进行快速排序
QuickSort(arr,key+1,end);
}
}
/**
* 实现i与j位置的元素交换
* @param arr 数组
* @param i 下标
* @param j 下标
*/
private static void swap(int[] arr,int i,int j){
//健壮性判断
if(arr==null || arr.length<=0){
System.out.println("数组为空!");
return;
}
//定义临时变量temp实现交换
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
/**
* 输出数组元素
* @param arr
* @return
*/
private static String printArray(int[] arr){
if(arr==null){
System.out.println("数组为空!");
return null;
}
StringBuffer sb = new StringBuffer();
for(int i=0;i<arr.length;i++){
sb.append(arr[i]);
}
return sb.toString();
}
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 行为型设计模式:访问者模式
- redis实战第十篇 集群收缩
- redis实战第九篇 集群扩容自动迁移槽(redis-cli)
- 自动化运维| Ansible playbook的逻辑控制语句
- Windows通用应用平台UWP持久化
- redis实战第八篇 集群扩容 手动迁移槽
- Xinetd服务的安装与配置详解
- redis实战第七篇 使用redis工具(redis-cli)搭建redis cluster
- 使用ROS2机器人操作系统进行多机器人编程技术实践(Multi-Robot Programming Via ROS2 )
- 自动化运维实践 | Ansible playbook重用
- 手把手教你打造高效的 Kubernetes 命令行终端
- docker save load export import的区别
- 使用ABAC控制数据访问
- linux 压力测试工具之ab
- 什么是Python Wheels?为什么要关心它?