JAVA算法系列汇总

公共代码

  • 打印数组
// 打印数组公用函数
    public void printArr(int[] arr) {
        System.out.print("[");
        for (int i = 0; i < arr.length; i++) {
            if (i != (arr.length - 1)) {
                System.out.print(arr[i] + ",");
            } else {
                System.out.print(arr[i] + "]");
                System.out.println();
            }
        }
    }
  • 不用中间变量实现两个变量的交换
    用异或的方式:
public static void main(String[] args) {
        int x = 8;
        int y = 9;
        //交换两个变量
        x = x ^ y;
        y = x ^ y;
        x = x ^ y;
        System.out.println("x=" + x + ";" + "y=" + y);
    }

打印输出:x=9;y=8

冒泡排序

原理

冒泡排序也是最简单的排序方式,其原理就是比较两个相邻的元素,将值大的元素交换到右边。

代码

// 冒泡排序
    public void bubbleSort() {
        int[] array = {51, 12, 53, 1, 5, 64, 77, 89, 14, 124, 54, 3, 5,};
        for (int i = 0; i < array.length; i++) {
            for (int j = i + 1; j < array.length; j++) {
                if (array[i] > array[j]) {
                    //使用异或来交换,不用中间变量
                    //^是针对二进制的二目运算符。运算规则:两个二进制数值如果在同一位上相同,则结果中该位为0,否则为1
                    array[i] = array[i] ^ array[j];
                    array[j] = array[i] ^ array[j];
                    array[i] = array[i] ^ array[j];
                }
            }
        }
        printArr(array);
    }

快速排序

原理

  1. 先从数列中取出一个数作为基准数。
  2. 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
  3. 再对左右区间重复第二步,直到各区间只有一个数。
    图片来自网络

代码

//快速排序
    public void quickSort() {
        int[] array = {51, 12, 53, 1, 5, 64, 77, 89, 14, 124, 54, 3, 5,14};
        sort(array, 0, array.length - 1);
    }

    public void sort(int arr[], int low, int high) {
        int key = arr[low];
        int start = low;
        int end = high;
        while (start < end) {
            // 如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较
            while (start < end && arr[end] >= key) {
                end--;
            }
            if (start < end && arr[end] < key) {
                arr[start] = arr[start] ^ arr[end];
                arr[end] = arr[start] ^ arr[end];
                arr[start] = arr[start] ^ arr[end];
            }
            // 如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置
            while (start < end && arr[start] <= key) {
                start++;
            }
            if (start < end && arr[start] > key) {
                arr[start] = arr[start] ^ arr[end];
                arr[end] = arr[start] ^ arr[end];
                arr[start] = arr[start] ^ arr[end];
            }
        }
        // 此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用
        printArr(arr);
        //此时 start == end 都为关键值的索引位置
        //先判断start>low再次经行左边排序
        //左边序列。第一个索引位置到关键值索引-1
        if (start > low) {
            sort(arr, low, start - 1);
        }
        //左边依次排序执行完递归后,弹栈进行右边排序
        // 右边序列。从关键值索引+1到最后一个
        if (end < high) {
            sort(arr, start + 1, high);
        }
    }

选择排序

原理

选择排序,从头至尾扫描序列,找出最小的一个元素,和第一个元素交换,接着从剩下的元素中继续这种选择和交换方式,最终得到一个有序序列。
图片来自网络

代码

	//选择排序
    public void chooseSort() {
        int[] array = {51, 12, 53, 1, 5, 64, 77, 89, 14, 124, 54, 3, 5};
        int minIndex = 0;
        for (int i = 0; i < array.length; i++) {
            //问题的关键就是要找到后面最小的那个值 然后交换位置
            minIndex = i;
            for (int j = i; j < array.length; j++) {
                if (array[j] < array[minIndex]) {
                    minIndex = j;
                }
            }
            //两个值相等时不做交换
            if (i == minIndex) {
                continue;
            }
            //交换位置
            array[i] = array[i] ^ array[minIndex];
            array[minIndex] = array[i] ^ array[minIndex];
            array[i] = array[i] ^ array[minIndex];
            printArr(array);
        }
        printArr(array);
    }

插入排序

原理

直接插入的算法基本思想是:仅有一个元素的序列总是有序的,因此,对n个记录的序列,可从第二个元素开始直接到第n个元素,逐个向有序序列中执行插入操作,从而得到n个元素按关键字有序的序列
图片来自网络

代码

//插入排序
    public void insertSort() {
        int[] array = {51, 12, 53, 1, 5, 64, 77, 89, 14, 124, 54, 3, 5};
        for (int i = 1; i < array.length; i++) {
            int key = array[i];
            int j = i - 1;
            //当后面的元素值大于前面的元素值时执行插入
            while (j >= 0 && array[j] > key) {
                array[j + 1] = array[j];
                j--;
            }
            array[j + 1] = key;
        }
        printArr(array);
    }

二分法查找

实现查找指定数值在元素有序的数组中存储的位置(索引),返回该位置(索引)

原理

  1. 首先,从数组的中间元素开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。
  2. 如果目标元素大于/小于中间元素,则在数组大于/小于中间元素的那一半区域查找,然后重复步骤(1)的操作。
  3. 如果某一步数组为空,则表示找不到目标元素。
    图片来自网络

代码

//二分法查找
    public void binarySearch() {
        int array[] = {1, 3, 5, 5, 12, 14, 51, 53, 54, 64, 77, 89, 124, 135};
        int searchKey = 77;
        int index = search(array, searchKey);
        System.out.println("index = "+ index);
    }
    //二分查找法(折半查找法)
    public static int search(int[] arr, int number) {
        int min = 0;  //最小下标
        int max = arr.length - 1;   //最大下标
        int mid = 0;  //中间下标
        while (min <= max) {
            //没找到,更新范围继续找
            mid = (min + max) / 2;
            if (arr[mid] > number) {   //number在mid的左边
                max = mid - 1;  //改变最大下标
            } else if (arr[mid] < number) {  //number在mid的右边
                min = mid + 1;  //改变最小下标
            } else {
                return mid;
            }
        }
        return -1;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值