二分查找,冒泡排序

二分查找原理:
1. 一个排好序的数组
2.每次都是要比较的值和中间下标的数值比较,如果中间数值大,那左边的数值全部不符合,只查找中间数值右边的值,这时候中间下标+1就是查找的起始下标,因此a=m+1,然后在找出中间下标(注意右边的数的个数如果是偶数就是中间靠左一位为中间下标,是奇数就是正常正中间数为中间下标,比如总数为8那就是第四个数为中间下标,如果总数为9那就是第五个数为中间下标),继续和要查找的值作比较,以此类推
3.注意中间值要放循环内部


public class rfsf { 
    /***
     *  二分查找
     * @param args
     */
    public static void main(String[] args) {
        Integer array[]=new Integer[]{1,4,9,12,14,21,25,29,16,6,7,18,31,36,38,39};
        Arrays.sort(array);
        Integer value=25;
        int sherch = sherch(array, value);
        System.out.println("sherch==="+sherch);

    } 
    public static int sherch(Integer array[],int value){
        //a是最小值,r最大值  m是中间值
        int a=0,r=array.length-1,m;
        while (a<=r){
            //一定要注意 这个m中间值要在循环里面要一直变化,不然会死循环
            m=(a+r)/2;
            if(array[m]==value){
                return m;
            }else if(array[m]>value){
                r=m-1;
            }else{
                a=m+1;
            }
        }
        return -1;
    }
}

面试题:
一,有一个有序表为1,5,8,11,19,22,31,35,40,45,48,49,50当二分查找为48结点时,查找成功需要比较的次数是:
注意解题思路是:如果数组里的数是偶数那就是中间靠左一位开始查找,如果是奇数那就是中间,例如数组个数是16,那就是16/2=8-1 ,从第七个数开始查找。如果是17个数,那就是第九个数开始查找
1.数组个数是13,取第七个数是中间数就是31,这时发现31比48小,于是数31(不含31)右边总数是偶数还是奇数以此找出中间数
2,右边有六位数,于是取中间靠左一位为中间数就是45,发现45还是比48小,于是看45右边有几位数
3,有三位数,取中间数49,发现49比48大,于是往左边查找
4,这时候48是左边最后一位数了,也正是要查找的数,因此这里查找了,31,45,49,48 查找了四次


二,使用二分法在序列1,4,6,7,15,33,39,50,64,78,81,89,96中查找元素81时,需要经过多少次查找?
1.数组中的个数是13,第七个数就是中间数39,这时39比81小,往39右边查找
2. 39右边有有六位数,取中间靠左一位为中间值就是78,这时78比81小,往78右边查找
3,78右边有三位数,取中间值89,这时89比81大,往89左边查找。
4. 89左边就剩下81,也正是要查找的数,因此执行四次。
 

三,在拥有128个元素的数组中二分查找一个数,需要比较的次数最多不超过多少次
   128/2/2/2/2/2/2/2=0   刚好除7次,因此就是查找7次
     2的n次方=128  n=7
 

冒泡排序:
相邻两个值相比,如果前面的值大于后面的值就交换位置,一直循环到把数组排好序

public class mbsf {

    /**
     *  冒泡排序 (相领两个值相比,如果前面的值大于后面的值 就交换位置)
     * @param args
     */
    public static void main(String[] args) {
        Integer array[]=new Integer[]{1,12,18,14,31,16,4,6,7,38,39,29,9,21,25,36};
        int temp;       
        for(int i=0;i<array.length-1;i++){
          boolean is=false;
            for(int j=0;j<array.length-1-i;j++){
                if(array[j]>array[j+1]){
                    temp=array[j];
                    array[j]=array[j+1];
                    array[j+1]=temp;
                    is=true;
                }
            }
            System.out.println("第"+i+"轮冒泡排序后的结果==="+Arrays.toString(array)+"is==="+is);
            if(!is){  //如果一排执行完都没有交换位置,代表现在就是排好序了就不需要在往下执行了
                break;
            }
        }
        System.out.println("最后"+Arrays.toString(array));
    }
}

运行截图如下:发现第8轮和第9轮是重复的,其实到第8轮就可以停止循环了

第1轮冒泡排序后的结果===[1, 12, 14, 18, 16, 4, 6, 7, 31, 38, 29, 9, 21, 25, 36, 39]is===true
第2轮冒泡排序后的结果===[1, 12, 14, 16, 4, 6, 7, 18, 31, 29, 9, 21, 25, 36, 38, 39]is===true
第3轮冒泡排序后的结果===[1, 12, 14, 4, 6, 7, 16, 18, 29, 9, 21, 25, 31, 36, 38, 39]is===true
第4轮冒泡排序后的结果===[1, 12, 4, 6, 7, 14, 16, 18, 9, 21, 25, 29, 31, 36, 38, 39]is===true
第5轮冒泡排序后的结果===[1, 4, 6, 7, 12, 14, 16, 9, 18, 21, 25, 29, 31, 36, 38, 39]is===true
第6轮冒泡排序后的结果===[1, 4, 6, 7, 12, 14, 9, 16, 18, 21, 25, 29, 31, 36, 38, 39]is===true
第7轮冒泡排序后的结果===[1, 4, 6, 7, 12, 9, 14, 16, 18, 21, 25, 29, 31, 36, 38, 39]is===true
第8轮冒泡排序后的结果===[1, 4, 6, 7, 9, 12, 14, 16, 18, 21, 25, 29, 31, 36, 38, 39]is===true
第9轮冒泡排序后的结果===[1, 4, 6, 7, 9, 12, 14, 16, 18, 21, 25, 29, 31, 36, 38, 39]is===false
最后[1, 4, 6, 7, 9, 12, 14, 16, 18, 21, 25, 29, 31, 36, 38, 39]


改进,记录最后一次换值的下标为数组循环的最大值,因为最后一次换值的右边代表是排好序了

public class mbsf2 {
    public static void main(String[] args) {
        Integer array[]=new Integer[]{1,12,18,14,31,16,4,6,7,38,39,29,9,21,25,36};
        int temp,n=array.length-1;
        for(int i=0;i<array.length-1;i++){
            int last=0;
            for(int j=0;j<n;j++){  //n就是
                if(array[j]>array[j+1]){
                    temp=array[j];
                    array[j]=array[j+1];
                    array[j+1]=temp;
                    last=j;  //记录换值的下标
                }
            }
            n=last;  //记录一轮下来最后一次换值的下标
            if(n==0){
                break;
            }
            System.out.println("第"+i+"轮冒泡排序后的结果==="+ Arrays.toString(array)+"last=="+last);
        }
        System.out.println("最后"+Arrays.toString(array));
    }
}

运行结果如下:只有8次循环

第1轮冒泡排序后的结果===[1, 12, 14, 18, 16, 4, 6, 7, 31, 38, 29, 9, 21, 25, 36, 39]last==14
第2轮冒泡排序后的结果===[1, 12, 14, 16, 4, 6, 7, 18, 31, 29, 9, 21, 25, 36, 38, 39]last==13
第3轮冒泡排序后的结果===[1, 12, 14, 4, 6, 7, 16, 18, 29, 9, 21, 25, 31, 36, 38, 39]last==11
第4轮冒泡排序后的结果===[1, 12, 4, 6, 7, 14, 16, 18, 9, 21, 25, 29, 31, 36, 38, 39]last==10
第5轮冒泡排序后的结果===[1, 4, 6, 7, 12, 14, 16, 9, 18, 21, 25, 29, 31, 36, 38, 39]last==7
第6轮冒泡排序后的结果===[1, 4, 6, 7, 12, 14, 9, 16, 18, 21, 25, 29, 31, 36, 38, 39]last==6
第7轮冒泡排序后的结果===[1, 4, 6, 7, 12, 9, 14, 16, 18, 21, 25, 29, 31, 36, 38, 39]last==5
第8轮冒泡排序后的结果===[1, 4, 6, 7, 9, 12, 14, 16, 18, 21, 25, 29, 31, 36, 38, 39]last==4
最后[1, 4, 6, 7, 9, 12, 14, 16, 18, 21, 25, 29, 31, 36, 38, 39]


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值