二叉树搜索
思想如下:一般情况下我们只对在已排序好的数组中进行查找,若没有进行排序,我们必须首先对其进行排序,否则算法将是无效的;
已知数组arr[l..r],和姚查找的数x
- 第一步:取得数组的中间元素,并与x进行比较;
- 第二步:若相等,则返回middle;
- 第三步:若arr[middle]>x,则在数组的middle的右边进行查找;否则在数组的middle的左边进行查找。
java实现的代码如下:
package org.wrh.algorithmimplements;
import java.util.Arrays;
import java.util.Scanner;
//二叉树查找
public class BinarySearch {
public static void main(String[] args) {
/*
* 输入任意一个数组,先对其进行排序,然后对其进行二叉树查找
* */
int [] a=new int[10];
Scanner sc=new Scanner(System.in);
for(int i=0;i<a.length;i++){
System.out.println("input a number:");
a[i]=sc.nextInt();
}
System.out.println("input a need search number:");
int x=sc.nextInt();
//这里我们利用快速排序
System.out.println("排序前的数组如下:"+Arrays.toString(a));
quickSort(a,0,a.length-1);
System.out.println("排序后的数组如下:"+Arrays.toString(a));
//接下来进行二叉树查找,若查找到该元素,则返回该元素在数组中的位置
int index=binarySearch(a,0,a.length-1,x);
if(index==-1){
System.out.println("该元素不在数组中");
}
else{
System.out.println("该元素"+x+"在数组"+Arrays.toString(a)+"的第"+index+"位置");
}
}
private static int binarySearch(int[] a, int l,int r,int x) {
if(l<=r){//注意:这里有“=”号
int middle=l+(r-l)/2;
if(a[middle]==x){
return middle;
}
else if(a[middle]<x){
return binarySearch(a,middle+1,r,x);
}
else{
return binarySearch(a, l, middle-1, x);
}
}
return -1;
}
private static void quickSort(int[] arr, int l, int r) {
if(l<r){
int q=partition(arr,l,r);
quickSort(arr,l,q-1);
quickSort(arr,q+1,r);
}
}
private static int partition(int[] arr, int l, int r) {
/*
* 选取第一个数组元素为主元
* */
int x=arr[l];
int i=l;
for(int j=l+1;j<=r;j++){
if(arr[j]<=x){
i++;
swap(arr,i,j);
}
}
swap(arr,i,l);
return i;
}
private static void swap(int[] arr, int i, int j) {
if(i!=j){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
代码中的简单说明:
- 这里的代码我是首先对数组进行了排序,这样我们就可以输入任意的数组都可以来进行二叉树的查找
总结
- 相比直接在数组中查找元素的时间复杂度O(n),我们的二叉树查找的时间复杂度为O(logn),不过前提条件下,是需要我们的数组是排好序了的
最后,关于BinarySearch的更多知识以及C语言的实现代码可以参考这里
最后的最后,要感谢geeksforgeeks这个网站,真的对我研究算法的帮助很大,通过它我既可以了解各种算法由C语言的实现方式,也可以锻炼自己由java语言来进行实现,无论我们选择任何一种语言来实现,其本质是一样的,是存在细微的一点区别。
最后的最后的最后,我不知道在geeksforgeeks学习的各种算法,然后我由java语言实现不知道是不是属于我的原创,若有侵权行为,请告知我,谢谢
也要说明的是,欢迎转载,但请注明出处,谢谢
修正:在上面的binarySearch函数中的
if(l<=r){//注意:这里有“=”号
这样才能保证边界被正确的检测出来
之所以会有这个修正的原因是:一个同学问了一个这样的问题:说当有一个长度为3的序列,例如:1,3, 5这样的序列,假如我们要查找5是否在此序列中,按照我们没有写“=”的代码逻辑:我们会进行一次然后就会退出,导致的查找的结果就是:“5”根本不在序列中,这也就说我们不能正确的进行边界的检测,因此我们要加上“=“才能进行正确的边界检测
- 通过以上说明了在我们的学习中和别人讨论的重要性
- 通过讨论我们才会发现原以为我们懂了的东西还是有一定的漏洞存在