您的位置:首页 > 编程语言 > Java开发

编程之美2.11寻找最近点对Java版一

2016-06-21 23:16 429 查看
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
*
* 2.11寻找最近的点对
*/
public class SearchLengthMinPoints {

public static void main(String[] args) {
int[] arry = new int[]{8,3,12,18,26};
//解法一   一维 把每两个点之间的距离都求出来;二维情况一样,求两点间距离|x1-x2|^2+|y1-y2|^2再开根号
int[] num1 = searchLength1(arry);
System.out.println("距离最近的两个点:" + num1[0] + "、" + num1[1]);

//解法二  先排序,然后求两点间距离;无法扩展到二维
int[] num2 = searchLength2(arry);
System.out.println("距离最近的两个点:" + num2[0] + "、" + num2[1]);

//解法三  一维 分治思想
List<Integer> list = new ArrayList();
for (int i = 0; i < arry.length; i++) {
list.add(arry[i]);
}
List<Integer> num3 = searchLength3(list);
System.out.println("距离最近的两个点:" + num3.get(0) + "、" + num3.get(1) + "距离为:" + num3.get(2));
}

private static int[] searchLength1(int[] arry) {
int[] result = new int[2];
int sub = Math.abs(arry[0] - arry[1]);
for (int i = 0; i < arry.length; i++) {
for (int j = i + 1; j < arry.length; j++) {
int tmp = Math.abs(arry[i] - arry[j]);
if (sub > tmp) {
sub = tmp;
result[0] = arry[i];
result[1] = arry[j];
}
}
}
return result;
}

private static int[] searchLength2(int[] arry) {
int[] result = new int[2];
quick_sort(arry, 0, arry.length - 1);
int sub = Math.abs(arry[0] - arry[1]);
for (int i = 2; i < arry.length; i++) {

int tmp = Math.abs(arry[i - 1] - arry[i]);
if (sub > tmp) {
sub = tmp;
result[0] = arry[i - 1];
result[1] = arry[i];
}

}
return result;
}

static void quick_sort(int s[], int l, int r) {
if (l < r) {
//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
int i = l, j = r, x = s[l];
while (i < j) {
while (i < j && s[j] >= x) // 从右向左找第一个小于x的数
{
j--;
}
if (i < j) {
s[i++] = s[j];
}

while (i < j && s[i] < x) // 从左向右找第一个大于等于x的数
{
i++;
}
if (i < j) {
s[j--] = s[i];
}
}
s[i] = x;
quick_sort(s, l, i - 1); // 递归调用
quick_sort(s, i + 1, r);
}
}

private static List<Integer> searchLength3(List<Integer> list) {
List result = new ArrayList();
if (list.size() <= 2) {
if (list.size() == 2) {
result.add(list.get(1));
result.add(list.get(0));
result.add(Math.abs(list.get(0) - list.get(1)));

} else {
result.add(list.get(0));
result.add(list.get(0));
result.add(0);
}

return result;

}
int mid = list.size() / 2;
int k = list.get(mid);
List<Integer> list_left = new ArrayList<Integer>();
List<Integer> list_right = new ArrayList();
for (int i = 0; i < list.size(); i++) {
if (list.get(i) < k) {
list_left.add(list.get(i));
} else if (list.get(i) > k) {
list_right.add(list.get(i));
}
}

if (list_left.size() > list_right.size()) {
list_right.add(k);
} else {
list_left.add(k);
}

List<Integer> result_left = searchLength3(list_left);
List<Integer> result_right = searchLength3(list_right);
//左边的最大值和右边的最小值的差
Collections.sort(list_left);
Collections.sort(list_right);
int sub = Math.abs( list_left.get(list_left.size()-1)- list_right.get(0));
int sub_left = result_left.get(2);
int sub_right = result_right.get(2);
if (sub_left > 0 && result_left.get(2) < sub) {
if (sub_right > 0 && sub_right < sub_left) {
result.addAll(result_right);
} else {
result.addAll(result_left);
}
} else {
if (sub_right > 0 && sub_right < sub) {
result.addAll(result_right);
} else {
result.add(list_left.get(list_left.size()-1));
result.add(list_right.get(0));
result.add(sub);
}
}

return result;
}
}
没觉得一维的分治算法有多简化啊。。。还是我的代码太复杂了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: