• 冒泡排序

    /**
     * 冒泡排序
     * 原理:从前往后,依次比较相邻两个数大小,如果arr[i]大于arr[i+1],则交换他们的位置
     * 即将比较大的数往后放,小的数往前走
     */
    private static void bubbleSort(int[] arr) {
        // 临时变量
        int temp;
        // 数组长度
        int len = arr.length;
        // 数据交换标记:循环开始时置为true
        // 如果有数据交换(有排序行为),则置为false
        // 如果无数据交换(无排序行为),说明当前数组已经是有序的,则跳出循环
        Boolean flag;
        for (int i = 0; i < len - 1; i++) {
            flag = true;
            for (int j = 0; j < len - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    // 交换前后位置
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    // 数据交换标记
                    flag = false;
                }
            }
            // 没有发生交换(表示已经是有序的了)则退出循环;
            if (flag) {
                break;
            }
        }
    }

 

  • 插入排序
    /**
     * 插入排序
     * 原理:在保证arr[i]前面的元素都是有序的前提下,将temp = arr[i]依次与前面的元素比较大小
     * 如果arr[i-1]大于temp则将arr[i-1]后移一位,直到arr[i-n]不大于temp为止
     * 然后将temp插入到(i-n+1)这个为止
     */
    private static void insertSort(int[] arr) {
        int i, j, temp;
        int len = arr.length;
        // 从arr[1]开始
        for (i = 1; i < len; i++) {
            j = i;
            // 将目标元素放入临时变量
            temp = arr[i];
            // 将temp依次与前面的元素进行比较
            // 如果temp小于arr[i-1]则将arr[i-1]后移一位,如果temp小于arr[i-2]则将arr[i-2]后移一位。。。
            // 最终将所有大于temp的元素都后移了一位,然后将temp插入当前空位置
            while (j > 0 && arr[j - 1] > temp) {
                arr[j] = arr[j - 1];
                j--;
            }
            // 将temp插入当前空位置
            arr[j] = temp;
        }
    }

注:此代码还可以优化
  • 二分插入排序
    /**
     * 二分插入排序
     * 原理:在保证arr[i]前面的元素都是有序的前提下
     * 利用二分法找到arr[i]前面数组中第一个大于temp(待插入元素)的元素的索引位置index
     * 然后将所有大于temp的元素全部后移一位
     * 将temp插入index位置
     */
    private static void binaryInsertSort(int[] arr) {
        int i, j, L, R, M,index,temp;
        int len = arr.length;
        
        for (i = 1; i < len; i++) {
            // 将目标元素放入临时变量
            temp = arr[i];

            // 二分法查找第一个大于当前元素temp的值 start
            L = 0;
            R = i - 1;
            index = i;
            while (L <= R) {
                M = (L + R) / 2;
                if(L == R){
                    index = M;
                }
                if (arr[M] <= temp) {
                    L = M +1;
                    continue;
                }
                if (arr[M] > temp) {
                    R = M;
                }
            }
            // 二分法查找第一个大于当前元素的值 end

            // 将满足条件的从index到i-1位置的元素全部后移一位
            for (j = i - 1; j >= index; j--){
                arr[j + 1] = arr[j];
            }

            // 将目标元素的值插入index位置
            arr[index] = temp;
        }
    }

    // 附:二分法查找第一个大于目标值得索引位置
    public static int searchFirstLargeThanThisValue(int[] arr, int value) {
        int L = 0,
            R = arr.length - 1,
            M = -1;
        while (L <= R) {
            M = (L + R) / 2;
            if(L == R){
                return  M;
            }
            if (arr[M] <= value) {
                L = M +1;
                continue;
            }
            if (arr[M] > value) {
                R = M;
            }
        }
        return M;
    }

 

  • 快速排序
    /**
     * 快速排序
     * 原理:利用三数取中法,选择一个合适的数作为基数,将基数放到数组最左边(位置L)
     * 先从后往前查找,找到比基数小的数(位置j)停止
     * 再从前往后查找,找到比基数大的数(位置i)停止,如果i=j时还没找到则停止
     * 直到 i = j 时,交换arr[i]和基数的位置,此时完成一次比较,保证基数左边的数都比基数小,右边的数都比基数大;
     * 然后分别递归基数左边数组和右边数组
     */
    private static void quickSort(int[] arr, int L, int R) {
        // 当左边大于右边时,退出迭代
        if (L > R) {
            return;
        }

        // 临时变量
        int temp;
        // 三数取中法,取一个合适的数(中间值)作为排序的基数,将基数放到数组最左边
        // 比较 L,R,M 三个位置元素的大小,将最大的数放到最右边,将最小的数放到中间,将中间的数放到最左边
        int M = (L + R)/2;
        if (arr[L] > arr[R]) {
            temp = arr[L];
            arr[L] = arr[R];
            arr[R] = temp;
        }
        if (arr[M] > arr[R]) {
            temp = arr[M];
            arr[M] = arr[R];
            arr[R] = temp;
        }
        if (arr[L] < arr[M]) {
            temp = arr[L];
            arr[L] = arr[M];
            arr[M] = temp;
        }

        // 选取数组第一个元素作为基数
        int base = arr[L];
        int i = L;
        int j = R;
        while (i < j) {
            // 先从后往前查找,找到第一个比基数小的数(位置 j)停止
            while (i < j && arr[j] >= base ) {
                j--;
            }
            // 再从前往后查找,找到第一个比基数大的数停止,如果i=j时还没找到则停止
            while (i < j  && arr[i] <= base) {
                i++;
            }
            // 如果此时 i<j,则交换arr[i] 和 arr[j] 的位置
            if (i < j) {
                temp = arr[j];
                arr[j] = arr[i];
                arr[i] = temp;
            }
        }

        // 走到这里说明已跳出while循环,即i=j了,则交换arr[i] 和 基数 的位置
        arr[L] = arr[i];
        arr[i] = base;

        // 走到这里基数的位置已经交换,此时满足基数左边的元素都小于等于基数,基数右边的元素都大于等于基数
        // 以当前基数的位置将数组分治,分别递归基数两边的数组
        quickSort(arr, L, i - 1);// 递归左半数组
        quickSort(arr, i + 1, R);// 递归右半数组
    }
  • 归并排序 

java-排序算法

    /**
     * 归并排序
     * 原理:
     * 首先创建一个与待排序数组大小相等的临时数组 temp ,用来存放合并后的序列;
     * 采用分治法
     */
    private static void mergeSort(int[] arr, int L, int R, int[] temp) {
        if (L < R) {
            int mid = (L + R) / 2;

            //左边归并排序,使得左子序列有序
            mergeSort(arr, L, mid, temp);

            //右边归并排序,使得右子序列有序
            mergeSort(arr, mid + 1, R, temp);

            //将两个有序子数组合并操作
            merge(arr, L, mid, R, temp);
        }
    }
    private static void merge(int[] arr, int L, int mid, int R, int[] temp) {
        int i = L;//左序列指针
        int j = mid + 1;//右序列指针
        int t = 0;//临时数组指针
        while (i <= mid && j <= R) {
            if (arr[i] <= arr[j]) {
                temp[t++] = arr[i++];
            } else {
                temp[t++] = arr[j++];
            }
        }
        while (i <= mid) {//将左边剩余元素填充进temp中
            temp[t++] = arr[i++];
        }
        while (j <= R) {//将右序列剩余元素填充进temp中
            temp[t++] = arr[j++];
        }
        t = 0;
        //将temp中的元素全部拷贝到原数组中
        while (L <= R) {
            arr[L++] = temp[t++];
        }
    }

 

相关文章: