传说中的二分查找和快速排序
1、二分查找
/* 二分查找(折半查找),前提是在已经排好序的数组中 通过将待查找的元素与中间索引值对应的元素进行比较, 若大于中间索引值对应的元素,去右半部分查找,否则去左半部分查找 一次类推,知道找到位置 */public class Test8{ public static void main(String[] args){
int[] nums={10,20,50,65,88,90};//待查找数组
int index= binarySearch(nums,90);
System.out.println(index);
} //二分查找数列
public static int binarySearch(int[] num,int key){ int start=0;//开始下标
int end=num.length-1;//结束下标
while(start<=end){ int middle=(start+end)/2;//>>>1
if(num[middle]>key){
end=middle-1;
}else if(num[middle]<key){
start=middle+1;
}else{ return middle;
}
} return -1;
}
}
其实这个二分查找在JDK里也有的,JDk已经帮我们写好了,嘻嘻,但是我们也得知道它怎么查找的是不是!
2、Arrays类
专门用来操作数组的一个类,我们只介绍几种常用的方法
- 使用二分法查找
我们每当学习别人的代码的时候,我们一定要先看文档看API文档,这个类有什么方法,每个方法是干啥的,全整的明明白白!上图,呸,上文档!
文档下载地址下载完解压,然后有个API文件夹,打开index,就是你想要的东西,见证奇迹的时候到了!
然后咱找找,Arrays
哎,是不是看到了一个熟悉的方法,就是咱们刚刚写的那个方法binarySearch(),二分查找,那我们看一样JDK里的二分查找怎么是实现的呢,咱们去遛一眼源码去!gogogo去JDK SRC目录下,util包里有一个Arrays类打开看看吧!
这个方法没有提供具体的实现,但是它调了一个binarySearch0()这个方法
看这个方法,思路是不是和我们的思路一样呢!
- 数组内容转成字符串的形式输出
你看我们在上一篇博客中,查看数组内容是怎么查看的呢,是遍历遍历的时候挨个输出,但是我们有了Array这个类后,就很方便了嘛!
这个也是遍历,然后拼接起来了,看起来更好看一点!
- 数组排序
Arrys里的排序是用的什么排序呢Quicksort快速排序,looklook快排的源码!
/* * Sorting methods for seven primitive types. */
/** * Sorts the specified range of the array using the given * workspace array slice if possible for merging * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted * @param work a workspace array (slice) * @param workBase origin of usable space in work array * @param workLen usable size of work array */
static void sort(int[] a, int left, int right, int[] work, int workBase, int workLen) { // Use Quicksort on small arrays
if (right - left < QUICKSORT_THRESHOLD) {
sort(a, left, right, true); return;
} /* * Index run[i] is the start of i-th run * (ascending or descending sequence). */
int[] run = new int[MAX_RUN_COUNT + 1]; int count = 0; run[0] = left; // Check if the array is nearly sorted
for (int k = left; k < right; run[count] = k) { if (a[k] < a[k + 1]) { // ascending
while (++k <= right && a[k - 1] <= a[k]);
} else if (a[k] > a[k + 1]) { // descending
while (++k <= right && a[k - 1] >= a[k]); for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) { int t = a[lo]; a[lo] = a[hi]; a[hi] = t;
}
} else { // equal
for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) { if (--m == 0) {
sort(a, left, right, true); return;
}
}
} /* * The array is not highly structured, * use Quicksort instead of merge sort. */
if (++count == MAX_RUN_COUNT) {
sort(a, left, right, true); return;
}
} // Check special cases
// Implementation note: variable "right" is increased by 1.
if (run[count] == right++) { // The last run contains one element
run[++count] = right;
} else if (count == 1) { // The array is already sorted
return;
} // Determine alternation base for merge
byte odd = 0; for (int n = 1; (n <<= 1) < count; odd ^= 1); // Use or create temporary array b for merging
int[] b; // temp array; alternates with a
int ao, bo; // array offsets from 'left'
int blen = right - left; // space needed for b
if (work == null || workLen < blen || workBase + blen > work.length) {
work = new int[blen];
workBase = 0;
} if (odd == 0) {
System.arraycopy(a, left, work, workBase, blen);
b = a;
bo = 0;
a = work;
ao = workBase - left;
} else {
b = work;
ao = 0;
bo = workBase - left;
} // Merging
for (int last; count > 1; count = last) { for (int k = (last = 0) + 2; k <= count; k += 2) { int hi = run[k], mi = run[k - 1]; for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) { if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) {
b[i + bo] = a[p++ + ao];
} else {
b[i + bo] = a[q++ + ao];
}
}
run[++last] = hi;
} if ((count & 1) != 0) { for (int i = right, lo = run[count - 1]; --i >= lo;
b[i + bo] = a[i + ao]
);
run[++last] = right;
} int[] t = a; a = b; b = t; int o = ao; ao = bo; bo = o;
}
}
代码很长,有兴趣的同学可以研究研究逻辑!
- 复制指定的数组
Arrays.copyOf(int[] array, int length);//int 返回新数组的长度
Arrays.copyOf(int[] array, int from, int to); //复制某一段
System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { @SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength)); return copy;
}
由此得出,数组复制效率由高到低排序是System.arraycopy>Arrays.copyOf
- 判断两个数组是否相等Arrays.equels();
- 使用指定元素填充数组Arrays.fill();