【8种排序算法】Java实现

import java.util.Arrays;

/**
 * 
 * 1. 冒泡排序
 * 2. 选择排序
 * 3. 直接插入排序
 * 4. 希尔排序
 * 5. 快速排序
 * 6. 归并排序
 * 7. 堆排序
 * 8. 基数排序
 * 
 * @author CN
 *
 */
public class SortUtils {

    public static void main(String[] args) {
        int[] arr= {49,38,65,97,76,13,27};

//      bubleSort(arr);
//      selectSort(arr);
//      insertSort(arr);
//      shellSort(arr);
//      quickSort(arr, 0, arr.length-1);
//      RadixSort(arr, 2);
//      heapSort(arr);
//      mergeSort(arr);
        System.out.println(Arrays.toString(arr));
    }


    /**
     * 1. 冒泡排序
     * @param arr
     */
    public static void bubleSort(int[] arr) {
        for(int i=0; i<arr.length; i++)
            for(int j=0; j<arr.length-i-1; j++)
                if(arr[j] > arr[j+1])
                    swap(arr, j, j+1);
    }


    /**
     * 2. 选择排序
     * @param arr
     */
    public static void selectSort(int[] arr) {
        int pos = 0;
        for(int i=0; i<arr.length; i++) {
            pos = i;
            for(int j=i+1; j<arr.length; j++)
                if(arr[j] < arr[pos])
                    pos = j;
            swap(arr, i, pos);
        }
    }


    /**
     * 3. 直接插入排序
     * @param arr
     */
    public static void insertSort(int[] arr) {
        for(int i=1; i<arr.length; i++)
            for(int j=i; j>0 && arr[j]<arr[j-1]; j--)
                swap(arr, j, j-1);
    }


    /**
     * 4. 希尔排序
     * @param arr 原数组
     */
    public static void shellSort(int[] arr) {
        for(int dk=arr.length/2; dk>0; dk/=2) {
            // 从第dk个元素,逐个对其所在组进行直接插入排序操作
            for(int i=dk; i<arr.length; i++) {
                for(int j=i; j-dk>=0 && arr[j]<arr[j-dk]; j -= dk)
                    swap(arr, j, j-dk);
            }
        }
    }


    /**
     * 5. 快速排序
     * @param arr 原数组
     * @param low 开始位置
     * @param high 结束位置
     */
    public static void quickSort(int[] arr, int low, int high) {
        int key = arr[low]; // 选择枢轴
        int i = low;
        int j = high;

        while(i < j) {
            while(i < j && key <= arr[j]) j--; // 从后往前
            if(i < j)  arr[i++] = arr[j]; // 小值前放

            while(i < j && key >= arr[i])  i++; // 从前往后
            if(i < j)  arr[j--] = arr[i]; // 大值后放
        }
        arr[i] = key;

        // 左侧排序
        if(i-1 > low) quickSort(arr, low, i-1);
        // 右侧排序
        if(i+1 < high) quickSort(arr, i+1, arr.length-1);
    }


    /**
     * 6. 归并排序
     * @param arr 原数组
     */
    public static void mergeSort(int[] arr) {
        divide(arr, 0, arr.length-1);
    }
    /** 分 */
    public static void divide(int[] arr, int left, int right) {
        if(left < right) {
            // 对半拆分
            int mid = (left + right)/2;
            divide(arr, left, mid);
            divide(arr, mid+1, right);
            // 两个分组进行合并
            merge(arr, left, mid+1, right);
        }
    }
    /** 治 */
    public static void merge(int[] arr, int left, int mid, int right) {
        int len = right-left+1;
        int[] tmp = new int[len];
        int i = 0;
        int j = left;
        int k = mid;
        while(i < len) {
            if(k > right) { // 如果右分组已全部被使用,将左分组全部移至至临时数组中
                System.arraycopy(arr, j, tmp, i, mid-j);
                break;
            }
            while(j<mid && arr[j]<arr[k]) // 如果左分组的第一个小,则移至临时数组
                tmp[i++] = arr[j++];
            if(j >= mid) { // 如果左分组已全部被使用,将右分组全部移至临时数组中
                System.arraycopy(arr, j, tmp, i, right-k+1);
                break;
            }
            while(k<=right && arr[k]<arr[j]) // 如果右分组的第一个小,则移至临时数组
                tmp[i++] = arr[k++];
        }
        // 将临时数组复制至原数组中
        System.arraycopy(tmp, 0, arr, left, len);
    }


    /**
     * 7. 堆排序(大顶堆-升序)
     * @param arr 原数组
     */
    public static void heapSort(int[] arr) {
        // 构造大顶堆
        for(int i=arr.length/2-1; i>=0; i--) {
            adjustHeap(arr, i, arr.length);
        }
        // 选出最大值置于尾部,并调整堆
        for(int i=arr.length-1; i>=0; i--) {
            swap(arr, 0, i); // 交换至尾部
            adjustHeap(arr, 0, i); // 重新调整
        }
    }
    /**
     * 调整为堆大顶堆(在大顶堆的基础上)
     * @param arr 原数组
     * @param i 开始调整的位置
     * @param length 长度
     */
    public static void adjustHeap(int[] arr, int i, int length) {
        // 从左子节点开始
        for(int k=2*i+1; k<length; k=2*i+1) {
            // 判断右子节点是否比左节点大
            if(k+1 < length && arr[k]<arr[k+1])
                k = k+1;
            // 判断最大的子节点与父节点的大小
            if(arr[k] > arr[i]) {
                swap(arr, k, i);
                i = k;
            }
            else // 比子节点都大,退出循环
                break;
        }
    }
    /** 交换函数 */
    public static void swap(int arr[], int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }


    /**
     * 8. 基数排序
     * @param arr 原数组
     * @param maxLen 数字的最长位数
     */
    public static void RadixSort(int[] arr, int maxLen) {
        int[][] tmp = new int[10][arr.length];
        int[] nums = new int[10];
        int d = 1; // 第i位数
        int n = 1;
        while(d <= maxLen) {
            for(int i=0; i<arr.length; i++) {
                // 获取某一位数
                int lsd = arr[i] / n % (10*d);
                tmp[lsd][nums[lsd]++] = arr[i];
            }
            // 放回原数组
            int k = 0;
            for(int i=0; i<10; i++) {
                for(int j=0; j<nums[i]; j++) 
                    arr[k++] = tmp[i][j];
                nums[i] = 0;
            }
            d++;
            n *= 10;
            System.out.println(Arrays.toString(arr));
        }
    }
}

猜你喜欢

转载自blog.csdn.net/goldlone/article/details/81304734
今日推荐