冒泡排序,快速排序,二分查找法(java)

二分查找法原理:给定有序数组,查找给定的值V在数组中的位置,首先获取数组中间元素的值,与V匹配,V大,查右边,V小查左边,重复这个过程,直到匹配到最后一个元素.(当然,如果查找的数据有重复,这里的实现只返回某一个元素所在的位置,更准确的说是查找数组是否含有这个元素)
冒泡排序原理:给定数组从第一个元素(A)开始依次从第二个元素往后匹配,匹配到比A小的元素就调换A与这个元素的位置,再用这个新值继续往后匹配,这样方式第一遍依次匹配完之后,第一个元素A就是数组中的最小元素,之后再从第二个元素开始,依次匹配第三个元素之后的值,轮询完后,第二个元素就是第二小元素…
快速排序原理
快速排序的原理不是太好理解与实现,但是思想是要记住的.首先将数组中的第一个元素N(先理解以第一个元素为基准)找到某个位置P并将这个位置的元素M与N互换,并且执行操作,让左边的都比N小,右边的都比N大(怎么做最后面说),那么P位置就是N所有元素排好序的位置(因为排好序的数组中的某个元素左小右大,只是这里只找到N的合适位置,其他位置的元素还没有进行排序而已).
初始时的数组为:
{N…M…}
N找到合适位置后,数组如下所示:
{M…N…}
此时N找到了合适的位置,后面排序就不需要再参与,所以将数组逻辑划分成两个数组,N左边的为一个数组,N右边为一个数组.对逻辑划分的数组继续执行上面的过程,这样,每一个数组执行上面的过程就会为一个元素找到合适的位置,直到逻辑划分的数组里面只有一个元素,而这个元素当前的位置就是合适的位置.不太好理解,以{2,4,1,5,3}为例:
第一个元素2找到合适位置应该是3现在所在的位置,所以互换{4,2,1,5,3},但是上面说过要进行某个操作让,2左边元素都小于2,右边的都大于2,所以做了这个操作的话,数组应该是类似这样的{1,2,4,5,3},此时元素2找到了合适的位置,将2左边逻辑划分成了{1},右边划分成了{4,5,3},左边数组的成了一个元素,所以就是合适的位置,再看右边的数组,此时第一个元素是4,对4进行排序应该是{3,4,5},这个过程中做了4左边的元素小于4,右边元素大于4的操作.之后在将{3,4,5}进行逻辑切分,因为切分后{3},{5}都只有一个元素,所以也是合适位置,这时再看整个数组,就完成了{1,2,3,4,5}的排序.
上面所说的如何将第一个元素找到合适位置,并让左边比右边大.将第一个元素N缓存起来,之后从A右边开始依次往左扫描,扫描第一个到比N小的元素,然后B从左往右扫描,扫描到第一个比N大的元素,如果此时A与B没有碰头,就将两个元素位置交换,执行这一步直到AB碰头,AB碰头位置的元素与N进行交换,此时左边的都比N小,右边的都比N大.

public class EFCZ {

     /**
     * 递归方法获取元素所在位置
     *
     * @param arr   查找的数组
     * @param v     查找的值
     * @param start 查找开始位置
     * @param end   查找结束位置
     * @return 返回元素所在数组的位置,-1未找到
     */
    private static int getPosition(int[] arr, int v, int start, int end) {
        int mid = start + (end - start) / 2;
        if (start <= end) {
            int value = arr[mid];
            if (v == value) {
                return mid;
            } else if (v > value) {
                return getPosition(arr, v, mid + 1, end);
            } else {
                return getPosition(arr, v, start, mid - 1);
            }
        }
        return -1;
    }

    /**
     * 循环获取元素位置
     *
     * @param arr 查找的数组
     * @param v   查找的值
     * @return 返回元素所在数组的位置,-1未找到
     */
    private static int getPosition(int[] arr, int v) {
        int start = 0;
        int end = arr.length - 1;
        while (start <= end) {
            int mid = start + (end - start) / 2;
            int value = arr[mid];
            if (value == v) {
                return mid;
            } else if (v < value) {
                end = mid - 1;
            } else {
                start = mid + 1;
            }
        }
        return -1;
    }

    /**
     * 冒泡排序
     * @param arr
     */
    public static void sortByBubbling(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = i+1; j < arr.length; j++) {
                if (arr[i] > arr[j]) {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }
     /**
     * 快速排序
     * @param arr
     * @param start
     * @param end
     */
    public static void sortByQuick(int[] arr, int start, int end) {
        if(start>end) return ;
        int tmp = arr[start];
        int tmp2;
        int i= start;
        int j = end;
        while (i < j) {
            while (tmp <= arr[j]&&i<j) {
                j--;
            }
            while (tmp >= arr[i]&&i<j) {
                i++;
            }
            if (i < j) {
                tmp2 = arr[i] ;
                arr[i] = arr[j];
                arr[j]=tmp2;
            }
        }
        arr[start]=arr[i];
        arr[i]=tmp;
        sortByQuick(arr,0,i-1);
        sortByQuick(arr,i+1,end);
    }
    
    public static void main(String[] args) {
        int[] arr = {1,4,5,7,3,4,6,7,9,4};
        //数组排序
        //Arrays.sort(arr);(jdk自带方法)
        sortByBubbling(arr);
        //sortByQuick(arr, 0, arr.length - 1);
        int v = 8;
        //递归
        int position = getPosition(arr,v,0, arr.length-1);
        System.out.println(position);
        //while循环
        int position1 = getPosition(arr,v);
        System.out.println(position1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值