二分查找代码实现及相关递归练习

package sort;

import org.junit.Test;

import java.util.Arrays;

public class 二分查找 {

    @Test
    public void test05(){
        int[] arr = new int[200];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int)(Math.random()*1000);
        }

        /**
         * 在上面的arr数组当中,找第5小的元素的值
         */
        int data = select_no_k_value(arr, 0, arr.length-1, 5);
        System.out.println("data:" + data);
    }

    @Test
    public void test04(){
        int[] arr = new int[20];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int)(Math.random()*100);
        }

        quickSort(arr, 0, arr.length-1);
        System.out.println(Arrays.toString(arr));
    }

    private void quickSort(int[] arr, int i, int j) {
        if(i > j)
            return;

        /*if(j - i <= 20){
            insertSort(arr, i, j);
            return;
        }*/

        int l = partation(arr, i, j); // left == right
        quickSort(arr, i, l-1);
        quickSort(arr, l+1, j);
    }

    private int partation(int[] arr, int l, int r) {
        int val = arr[l];
        while(l < r){
            // 1. 从r开始往l的方向找第一个小于val的数字
            while(l < r && arr[r] > val){
                r--;
            }
            // 2. 把第一个小于val的元素值写入l里面,并且l++
            if(l < r){
                arr[l++] = arr[r];
            }
            // 3. 从l往r的方向找第一个大于val的数字
            while(l < r && arr[l] < val){
                l++;
            }
            // 4. 把第一个大于val的元素值写入r里面,并且r--
            if(l < r){
                arr[r--] = arr[l];
            }
        }
        arr[l] = val;
        return l;
    }

    @Test
    public void test03(){
        int[] arr = new int[]{2,5,7,54,89,320,1300};
        int idx = binarySearch(arr, 0, arr.length-1, 54);
        System.out.println("54 idx:" + idx);
    }

    /**
     * 递归实现二分查找
     * binarySearch在arr数组中从i到j的范围内,用二分查找搜索val
     * @param arr
     * @param i
     * @param j
     * @param val
     */
    private int binarySearch(int[] arr, int i, int j, int val) {
        if(i > j){
            return -1;
        }

        int mid = (i+j)/2;
        if(val < arr[mid]){ // i mid-1
            return binarySearch(arr, i, mid-1, val);
        } else if(val > arr[mid]){
            return binarySearch(arr, mid+1, j, val);
        } else {
            return mid;
        }
    }

    class Entry{
        int data;
        Entry next;

        public Entry(int data, Entry next) {
            this.data = data;
            this.next = next;
        }
    }

    @Test
    public void test02(){
        Entry root = new Entry(0, null);
        Entry n1 = new Entry(10, null);
        Entry n2 = new Entry(10, null);
        Entry n3 = new Entry(10, null);
        Entry n4 = new Entry(10, null);
        root.next = n1;
        n1.next = n2;
        n2.next = n3;
        n3.next = n4;

        System.out.println("链表有效节点的数量:" + func4(root));
    }

    /**
     * 返回以root为根节点的单链表有效节点的数量,用递归实现
     * @param root
     * @return
     */
    private int func4(Entry root) {
        if(root == null){
            return 0;
        } else {
            return 1 + func4(root.next);
        }
    }


    /**
     * 递归函数: 函数调用自己
     * 求n!
     */
    @Test
    public void test01(){
        int n = 6;
        /*int sum = 1;
        for (int i = 1; i <= n; i++) {
            sum *= i;
        }
        System.out.println("6!=" + sum);*/
        //System.out.println("6!=" + func1(n));

        // 求斐波那契数列 1 1 2 3 5 8 13
        // func2求指定个数的斐波那契数字的值
        // func2(20);

        // 实现一个递归函数func3,判断arr数组是否是一个递增序列的数组 true false
        int[] arr = new int[]{2,5,7,8,54,321,1300};
        System.out.println(func3(arr));
    }

    /**
     * 判断arr数组是否是递增的数组
     * @param arr
     * @return
     */
    private boolean func3(int[] arr) {
        return func3(arr, 0, arr.length-1);
    }

    private boolean func3(int[] arr, int i, int j) {
        if(i+1 > j){
            return true;
        }
        if(arr[i] > arr[i+1]){
            return false;
        }
        return func3(arr, i+1, j);
    }

    /**
     * 1 1
     * @param n
     * @return
     */
    private int func2(int n) {
        if(n == 1 || n == 2){
            return 1;
        } else {
            return func2(n-1) + func2(n-2);
        }
    }

    /**
     * 求阶乘的函数
     * java.lang.StackOverflowError 栈溢出
     * @param n
     * @return
     */
    private int func1(int n) {
        if(n==0 || n==1){ // 范围缩小到递归条件成立的时候
            return 1;
        } else {
            return n*func1(n-1);
        }
    }

    public static void main(String[] args) {
        //int[] arr = new int[]{12,5,7,89,54,32,13};

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值