剪枝搜索方法:
基本思想:利用计算问题的特征,剪除不影响问题求解的输入数据,由剩下的输入数据构成一个与原问题形式相同,但规模更小的子问题,递归求解子问题得到原问题的解。
正确性:其正确性由剪枝策略的正确性保证。
算法复杂度分析:
剪枝策略共剪除了λn个输入数据,其中n为问题的规模,则T(n)满足:
找最小的第k个数-线性选择算法
原理:
线性选择算法描述:
LinearSelect
输入:
输出:
线性选择算法的实现:
TreeMap
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
public class LinearSelect {
public static int table[][] = new int[200][5];
public static int a[]= new int[200];
public static int b[] = new int[100];
public static int c[] = new int[200];
public static int N=300;
public static void main(String[] args) {
Random random = new Random(12);
int nums[] = new int[N];
int i = 0;
while (i < N) {
nums[i] = random.nextInt()%1000;
table[i / 5][i % 5] = nums[i];
// System.out.println(nums[i]);
i++;
}
Arrays.sort(nums);
displayArrays(nums, 30);
System.out.println("ans :"+nums[N-15]);
printTable();
System.out.println();
System.out.println(new LinearSelect().findk(N,15));
System.out.println("job done...");
}
/*
*
*/
public int findk(int n,int k) {
if (n<=20) {
int arrays[]=new int[n];
int t0=0;
while (t0<n) {
arrays[t0]=table[t0/5][t0%5];
t0++;
}
Arrays.sort(arrays);
displayArrays(arrays, 20);
return arrays[n-k];
}
for (int i = 0; i <n/5; i++) {
Arrays.sort(table[i]);
}
printTable();
int midpoints[]=new int[n/5];
Map<Integer,Integer> map=new TreeMap<Integer, Integer>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
if (o1==o2) {
return 0;
}else if (o1>o2) {
return 1;
}else {
return -1;
}
}
});
for (int i = 0; i <n/5; i++) {
map.put(table[i][2],i);
}
System.out.println();
System.out.println(map.values());
List<Integer> list=new ArrayList<Integer>(map.values());
int x=0,y=0,z=0;
int m=list.size()/2;
int midValues=table[list.get(m)][2];
System.out.println("m="+list.get(m)+"midValues: "+table[list.get(n/10)][2]+" "+midValues);
for (int i = 0; i <m; i++) {
int row=list.get(i);
a[x++]=table[row][0];
a[x++]=table[row][1];
a[x++]=table[row][2];
for (int j = 3; j < 5; j++) {
if (table[row][j]<midValues) {
a[x++]=table[row][j];
}else if (table[row][j]>midValues) {
c[z++]=table[row][j];
}else {
b[y++]=table[row][j];
}
}
}
a[x++]=table[m][0];
a[x++]=table[m][1];
b[y++]=table[m][2];
c[z++]=table[m][3];
c[z++]=table[m][4];
for (int i =m+1; i <list.size(); i++) {
int row=list.get(i);
c[z++]=table[row][2];
c[z++]=table[row][3];
c[z++]=table[row][4];
for (int j = 0; j < 2; j++) {
if (table[row][j]<midValues) {
a[x++]=table[row][j];
}else if (table[row][j]>midValues) {
c[z++]=table[row][j];
}else {
b[y++]=table[row][j];
}
}
}
if (z>k) {
int t0=0;
int cc[]=new int[z];
while (t0<z) {
table[t0/ 5][t0 % 5] =c[t0];
cc[t0]=c[t0];
t0++;
}
Arrays.sort(cc);
displayArrays(cc,z>30?30:z);
while(t0%5!=0){
table[t0/ 5][t0 % 5] =-999; //数组补零,不影响最大
t0++;
}
return findk(z,k);
}else if (y+z<k) {
int t0=0;
while (t0<x) {
table[t0/ 5][t0 % 5] =a[t0];
t0++;
}
while(t0%5!=0){
table[t0/ 5][t0 % 5] =-999; //数组补零,不影响最大
t0++;
}
return findk(x,k-y-z);
}else {
return midValues;
}
}
public static void displayArrays(int nums[],int k) {
int i=1;
int n=nums.length;
while (i<k) {
System.out.print(String.format("%4d", nums[n-i]));
i++;
}
System.out.println();
}
public static void printTable() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < table.length; j++) {
System.out.print(String.format("%4d", table[j][i]));
}
System.out.println();
}
}
}