在实现之前,需要目标快速排序和二分查找
先贴上代码:二分查找
package com;
/**
* @Author: WYF
* @Description: 二分查找
* @Create: 2020/3/27 17:49
* @Version: 1.0
*/
public class MidFind {
public static void main(String[] args) {
int[] nums={-5,0,1,2,3,5,7,9,10,15,20,28,50,56};
System.out.println(searchInsert(nums,0,13,9));
}
public static int searchInsert(int[] num,int low,int high,int targe){
if (low>high ||
num.length == 0 || targe > num[high]|| targe < num[low]) {
return -1;
}
/**
* 两个优化:1.从 (high + low)/2改为low + (high-low)/2
* 2.改为 low+(high-low)*(index - arr[low])/(arr[high]-arr[low])
*/
int mid = low+(high-low)*(targe - num[low])/(num[high]-num[low]);
if (num[mid] > targe){
return searchInsert(num, low, mid-1, targe);
}else if (num[mid] < targe){
return searchInsert(num, mid+1, high, targe);
}else {
return mid;
}
}
}
接着是快排
package com.sort;
import java.util.Scanner;
/**
* @Author: WYF
* @Description: 快速排序
* @Create: 2020/2/7 0:12
* @Version: 1.0
*/
public class QuickSort {
/**
* public static只能修饰成员变量或者成员方法
* 原因:局部变量是随着方法调用而在内存开辟空间,方法结束而释放
* 而static,public是用来声明全局变量或是被其他对象引用的变量
*/
public static final int MAX = 100;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] arr = new int[MAX];
int length;
for (length = 0; length < MAX; length++) {
int a = scanner.nextInt();
if (a == 0) {
break;
}
arr[length] = a;
}
sort(arr, 0, length - 1);
for (int i = 0; i < length; i++) {
System.out.println(arr[i]);
}
}
private static void sort(int[] arr, int low, int high) {
int i = low;
int j = high;
int temp;
if (low > high) {
return;
}
while (i < j) {
while (arr[j] >= arr[low] && i < j) {
j--;
}
while (arr[i] <= arr[low] && i < j) {
i++;
}
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
temp = arr[low];
arr[low] = arr[j];
arr[j] = temp;
sort(arr, low, j - 1);
sort(arr, j + 1, high);
}
}
快排思想实现查找第n大的数
一、
我的排序是升序,而第n大的数字,在数字里的索引不是n,所以我要处理
如果你是降序,就做减一就好
例如在长度为8的升序数组里,第一大的数字对应索引为7,第二大对应为 6
二、
处理完1后,问题变成,在升序数组里查找索引为m的数字
利用快速排序的交换思想,从数组arr中随机找出一个元素X,把数组分为两部分arr(小)和arr(大)。arr(小)中的元素小于X,arr(大)中元素大于X。这时有三种情况:
- 元素X对应的索引 < m, 目标值必定在 arr(大)里面
- 元素X对应的索引 > m,则 目标值必定在 arr(小)里面
- X索引 = m,返回元素x
(注意,拿来和m比较的是元素X的索引,不是x本身)
代码:
package com.sort;
/**
* @Author: WYF
* @Description: 利用快速排序查第n大的数字:
* 基本思想:快速排序结合上二分查找
* @Create: 2020/5/24 18:37
*/
public class UseQucikSort {
public static void main(String[] args) {
int[] arr = new int[]{9,4,3,7,6,2,8,5};
int target = 1;
int num = findTarget(arr, target);
System.out.println(num);
}
private static int findTarget(int[] arr, int target) {
int num;
int length = arr.length;
if (target<=length) {
/**
* @Description: eg 在长度为8的数组里,第一大的数字对应索引为7,第二大对应为 6,处理target
*/
target = length - target;
num = quickSortFind(arr,0 ,arr.length-1, target);
return num;
}else {
throw new RuntimeException("请输入正确目标数字");
}
}
private static int quickSortFind(int[] arr, int low, int high,int target) {
int i = low;
int j = high;
int temp;
while (i < j) {
while (arr[j] >= arr[low] && i < j) {
j--;
}
while (arr[i] <= arr[low] && i < j) {
i++;
}
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
temp = arr[low];
arr[low] = arr[j];
arr[j] = temp;
if (target == j) {
return arr[j];
} else if (target < j) {
return quickSortFind(arr, low, j-1, target);
} else {
return quickSortFind(arr, j+1, high, target);
}
}
}