java常用排序算法

java常用排序算法

冒泡排序

public static void bubble(int[] arr) {
        int tem;
        for (int i = 1; i < arr.length; ++i) {
            // 负辅助变量,用于提前结束
            int count = 0;
            for (int j = 1; j < arr.length; ++j) {
                if (arr[j - 1] > arr[j]) {
                    tem = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = tem;
                    // 减少赋值判断
                    if (count == 0) {
                        ++count;
                    }
                }
            }
            if (count == 0) {
                break;
            }
        }
    }

选择排序

public static void select(int[] arr) {
    for (int i = 0; i < arr.length - 1; ++i) {
        // 找到最小值和下标
        int minIndex = i;
        int min = arr[i];
        for (int j = i + 1; j < arr.length; ++j) {
            if (min > arr[j]) {
                min = arr[j];
                minIndex = j;
            }
        }
        // 交换
        if (minIndex != i) {
            arr[minIndex] = arr[i];
            arr[i] = min;
        }
    }
}

插入排序

public static void insert(int[] arr) {
    for (int i = 1; i < arr.length; ++i) {

        int insertValue = arr[i];
        int insertIndex = i - 1;

        while (insertIndex >= 0 && insertValue < arr[insertIndex]) {
            arr[insertIndex + 1] = arr[insertIndex];
            --insertIndex;
        }
        arr[insertIndex + 1] = insertValue;
    }
}

希尔排序

交换法

public static void shell01(int[] arr) {
    int temp;
    for (int gap = arr.length / 2; gap > 0; gap /= 2) {
        for (int i = gap; i < arr.length; ++i) {
            for (int j = i - gap; j >= 0; j -= gap) {
                if (arr[j] > arr[j + gap]) {
                    temp = arr[j];
                    arr[j] = arr[j + gap];
                    arr[j + gap] = temp;
                }
            }
        }
    }
}

位移法

public static void shell02(int[] arr) {
        for (int gap = arr.length / 2; gap > 0; gap /= 2) {
            for (int i = gap; i < arr.length; ++i) {
                // 保存下标和值
                int index = i;
                int temp = arr[index];
                while (index - gap >= 0 && temp < arr[index - gap]) {
                    // 移动
                    arr[index] = arr[index - gap];
                    index -= gap;
                }
                arr[index] = temp;

            }
        }
    }

快速排序

public static void quick(int[] arr, int left, int right) {
        int l = left;
        int r = right;
        int mid = left + (right - left) / 2;
        int pivot = arr[mid];
        int temp = 0;

        // 结束条件为
        // 左下标在右下标右边就进不去了
        while (l < r) {

            // 找到左右需要交换的数
            while (arr[l] < pivot) {
                // 找不到移动下标
                ++l;
            }
            while (arr[r] > pivot) {
                --r;
            }
            // 找到后交换
            if (l >= r) {
                // 没找到
                break;
            }
            // 交换
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;

            // 如果交换完后发现左右值和中值相等的情况
            if (arr[l] == pivot) {
                --r;
            }
            if (arr[r] == pivot) {
                ++l;
            }
        }

        // 如果l == r,必须l右移,r左移
        if (l == r) {
            ++l;
            --r;
        }

        // 左递归
        if (left < r) {
            quick(arr, left, r);
        }
        // 右递归
        if (right > l) {
            quick(arr, l, right);
        }

    }

归并排序

/**
 * 分+合
 */
public static void mergeSort(int[] arr, int left, int right, int[] temp) {
    if (left < right) {
        // 分
        int mid = left + (right - left) / 2;
        // 向左递归分解
        mergeSort(arr, left, mid, temp);
        // 向右递归
        mergeSort(arr, mid + 1, right, temp);

        // 分解完合并
        merge(arr, left, mid, right, temp);
    }
}

/**
 * 合并
 *
 * @param arr   排序的原始数组
 * @param left  左边有序序列的初始索引
 * @param mid   中间索引
 * @param right 右边索引
 * @param temp  做中转的数组
 */
public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
    // 左边有序序列的初始索引
    int i = left;
    // 右边有序序列的初始索引
    int j = mid + 1;
    // temp数组的索引
    int t = 0;

    // 左右两边初始数组按规则拷贝到temp
    // 直到有一边的有序数组处理完毕
    while (i <= mid && j <= right) {
        // 判断
        if (arr[i] > arr[j]) {
            temp[t++] = arr[j++];
        } else if (arr[j] > arr[i]) {
            temp[t++] = arr[i++];
        } else {
            temp[t++] = arr[i++];
            temp[t++] = arr[j++];
        }
    }

    // 把有剩下数组的数据依次填充到temp
    while (i <= mid) {
        temp[t++] = arr[i++];
    }
    while (j <= right) {
        temp[t++] = arr[j++];
    }

    // 将temp数组copy到arr中
    t = 0;
    int tempLeft = left;
    while (tempLeft <= right) {
        arr[tempLeft++] = temp[t++];
    }
}

基数排序

public static void radix(int[] arr) {
    // 桶
    int[][] bucket = new int[10][arr.length];
    // 桶下标
    int[] bucketIndex = new int[10];

    // 找到最大值
    int max = arr[0];
    for (int i = 1; i < arr.length; i++) {
        max = arr[i] > max ? arr[i] : max;
    }
    // 得到最大值位数
    int maxLenth = (max + "").length();


    for (int i = 0, n = 1; i < maxLenth; ++i, n *= 10) {
        // 按规则放入桶
        for (int j = 0; j < arr.length; j++) {
            int element = (arr[j] / n) % 10;
            bucket[element][bucketIndex[element]++] = arr[j];
        }
        // 从桶里放到arr
        int index = 0;
        for (int k = 0; k < bucketIndex.length; k++) {
            // 如果桶里没数据就不管他
            if (bucketIndex[k] != 0) {
                // 循环放入
                for (int l = 0; l < bucketIndex[k]; l++) {
                    arr[index++] = bucket[k][l];
                }
            }
            bucketIndex[k] = 0;
        }
    }
}
posted @   CoderCatIce  阅读(43)  评论(0)    收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示