排序,查找算法在面试的时候经常会被问起,那么如何把这个问题回答得有水平。
从以下几点考虑:
- 有经验的程序员==不重复发明轮子
- 如果一定要实现,那么代码需要具备一定的架构设计能力,可复用,可以解决同一类问题(轮子的设计)
- 基础扎实,考虑算法的时空复杂度(轮子的实现)
不重复发明轮子
Java基础类库已经提供了这些功能,大部分时候直接使用工具类。
Integer[] arr = { 2, 5, 4, 10, 3 };
// 升序排序
Arrays.sort(arr);
// 降序排序
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer lhs, Integer rhs) {
return rhs - lhs;
}
});
// 查找
int location = Arrays.binarySearch(arr, 10);
/** ------------------------- 集合操作 --------------------------- */
ArrayList<Integer> list = new ArrayList<Integer>(Arrays.asList(arr));
// 排序
Collections.sort(list);
// 查找
Collections.binarySearch(list, 10);
Set<Integer> set = new TreeSet<Integer>(list);
使用泛型实现快速排序
如果一定要实现,就参考JDK源码的参考模仿写一个,抽象出一个排序接口,参考Map的子接口SortMap的Sort接口设计,把一类问题抽象出来。
接口:
public interface Sorter {
/**
* 待排序数据需要实现Comparable接口
*/
<T extends Comparable<T>> void sort(T[] arr);
/**
* @param arr
* 待排序数组
* @param comp
* 实现比较器
*/
<T> void sort(T[] arr, Comparator<T> comp);
}
快速排序实现:
public class QuicklySort implements Sorter {
@Override
public <T extends Comparable<T>> void sort(T[] arr) {
sort(arr, 0, arr.length - 1);
}
@Override
public <T> void sort(T[] arr, Comparator<T> comp) {
sort(arr, 0, arr.length - 1, comp);
}
private <T extends Comparable<T>> void sort(T[] arr, int s, int e) {
if (e <= s || s < 0 || e < 0) {
return;
}
int mid = findmid(arr, s, e);
sort(arr, s, mid - 1);
sort(arr, mid + 1, e);
}
private <T extends Comparable<T>> int findmid(T[] arr, int s, int e) {
int start = s, end = e;
T temp = arr[start];
while (start < end) {
while (arr[end].compareTo(temp) >= 0 && start < end) {
end--;
}
arr[start] = arr[end];
while (arr[start].compareTo(temp) <= 0 && start < end) {
start++;
}
arr[end] = arr[start];
}
arr[start] = temp;
return start;
}
private <T> void sort(T[] arr, int s, int e, Comparator<T> comp) {
if (e <= s || s < 0 || e < 0) {
return;
}
int mid = findmid(arr, s, e, comp);
sort(arr, s, mid - 1, comp);
sort(arr, mid + 1, e, comp);
}
private <T> int findmid(T[] arr, int s, int e, Comparator<T> comp) {
int start = s, end = e;
T temp = arr[s];
while (start < end) {
while (comp.compare(arr[end], temp) >= 0 && start < end) {
end--;
}
arr[start] = arr[end];
while (comp.compare(arr[start], temp) <= 0 && start < end) {
start++;
}
arr[end] = arr[start];
}
arr[start] = temp;
return start;
}
}
测试:
public void testSortTArray() {
Integer[] arrCopy = arr.clone();
Arrays.sort(arr);
sorter.sort(arrCopy);
for (int i = 0; i < arr.length; i++) {
assertEquals(arr[i], arrCopy[i]);
}
}
public void testSortTArrayComparatorOfT() {
Integer[] arrCopy = arr.clone();
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer lhs, Integer rhs) {
return rhs - lhs;
}
});
sorter.sort(arrCopy, new Comparator<Integer>() {
@Override
public int compare(Integer lhs, Integer rhs) {
return rhs - lhs;
}
});
for (int i = 0; i < arr.length; i++) {
L.d(arrCopy[i]);
assertEquals(arr[i], arrCopy[i]);
}
}
二分查找
接口:
public interface BinarySearch {
<T extends Comparable<T>> int search(T[] arr, int start, int end, T key);
<T> int search(T[] arr, int start, int end, T key, Comparator<T> comp);
}
实现
public class BinarySearchImp implements BinarySearch {
@Override
public <T extends Comparable<T>> int search(T[] arr, int start, int end,
T key) {
if (start <= end) {
int mid = start + ((end - start) >> 2);
if (arr[mid].compareTo(key) < 0) {
return search(arr, start, mid - 1, key);
} else if (arr[mid].compareTo(key) > 0) {
return search(arr, mid + 1, end, key);
} else {
return mid;
}
}
return -1;
}
@Override
public <T> int search(T[] arr, int start, int end, T key, Comparator<T> comp) {
if (start < end || start < 0 || end < 0) {
return -1;
}
int mid = start + (start - end) / 2;
if (comp.compare(key, arr[mid]) < 0) {
return search(arr, start, mid - 1, key, comp);
} else if (comp.compare(key, arr[mid]) > 0) {
return search(arr, mid, end, key, comp);
} else {
return mid;
}
}
}