几个排序算法的Java实现

package sort;

public class Sort {


    final static int SIZE = 10;

    public static void main(String[] args) {
        int[] list = new int[SIZE];

        inite(list);
        System.out.print("乱序的数组:");
        display(list);

        // insertionSort(list);
        // bubleSort(list);
        // mergeSort(list);
        quickSort(list);
        System.out.print("排好序的数组:");
        display(list);
    }

    // 使用随机数初始化数组
    public static void inite(int[] list) {
        for (int i = 0; i < list.length; i++) {
            list[i] = (int) (Math.random() * 10);
        }
    }

    // 打印数组
    public static void display(int[] list) {
        for (int e : list) {
            System.out.print(e + " ");
        }
        System.out.println();
    }

    // 插入排序O(n²),将新的元素插入到一个有序的数组,遍历有序数组找到插入位置
    public static void insertionSort(int[] list) {
        for (int i = 1; i < list.length; i++) {
            int temp = list[i];// 保存待插入元素
            int k;
            for (k = i - 1; k >= 0 && list[k] > temp; k--) {// 这里的循环条件必须是k>=0,避免k=-1时引用元素发生下标越界
                list[k + 1] = list[k];
            }
            list[k + 1] = temp;
        }
    }

    // 冒泡排序O(n²)、O(n),依次比较相邻元素,若不符合排序规则,则交换2个元素
    public static void bubleSort(int[] list) {
        boolean needNextPass = true;// 设置标志变量,若再一次循环中没有发生交换,则说明已经排好序
        for (int i = 1; i < list.length && needNextPass; i++) {
            needNextPass = false;// 将needNextPass初始化为false
            for (int k = 0; k < list.length - i; k++) {
                if (list[k] > list[k + 1]) {// 比较相邻2个元素
                    int temp = list[k + 1];
                    list[k + 1] = list[k];
                    list[k] = temp;
                    needNextPass = true;// 若发生交换,则说明还需要下一次循环排序
                }
            }
        }
    }

    // 归并排序O(nlogn),递归地将一个数组划分为2个子数组,然后将子数组递归地归并为一个数组
    public static void mergeSort(int[] list) {
        if (list.length > 1) {// 划分一直到子数组长度为1
            int[] firstHalf = new int[list.length / 2];
            System.arraycopy(list, 0, firstHalf, 0, firstHalf.length);// 复制数组元素
            mergeSort(firstHalf);

            int[] secondHalf = new int[list.length - list.length / 2];
            System.arraycopy(list, firstHalf.length, secondHalf, 0, secondHalf.length);
            mergeSort(secondHalf);

            merge(firstHalf, secondHalf, list);// 合并2个子数组到list数组中
        }
    }

    // 将2个数合并到list数组中
    public static void merge(int[] firstHalf, int[] secondHalf, int[] list) {
        int current1 = 0;// 各自的下标
        int current2 = 0;
        int current3 = 0;

        while (current1 < firstHalf.length && current2 < secondHalf.length) {// 循环地将2个子数组中较小的元素放入list数组中
            if (firstHalf[current1] < secondHalf[current2]) {
                list[current3++] = firstHalf[current1++];
            } else {
                list[current3++] = secondHalf[current2++];
            }
        }

        while (current1 < firstHalf.length) {// 将剩下的元素全部放入list数组中
            list[current3++] = firstHalf[current1++];
        }

        while (current2 < secondHalf.length) {
            list[current3++] = secondHalf[current2++];
        }
    }

    // 快速排序的辅助方法
    public static void quickSort(int[] list) {
        quickSort(0, list.length - 1, list);
    }

    // 快速排序O(nlogn)、O(n),将数组中小于主元pivot的元素放在pivot前,大于pivot的元素放在pivot后
    public static void quickSort(int first, int last, int[] list) {
        if (first < last) {// 循环一直持续到子数组的长度为1,因为没有创建子数组,所以这里的条件为first < last
            int pivotIndex = partition(first, last, list);// 得到划分后主元pivot的位置
            quickSort(first, pivotIndex - 1, list);// 递归地对pivot前的数组quickSort
            quickSort(pivotIndex + 1, last, list);// 递归地对pivot后的数组quickSort
        }
    }

    // 划分,将<主元pivot的元素放在pivot前,>pivot的元素放在pivot后,对于其中的关系符号> < >= <= 需要好好斟酌下
    public static int partition(int first, int last, int[] list) {
        int pivot = list[first];// 令第一个元素为主元pivot
        int low = first + 1;
        int high = last;

        while (low < high) {// 循环一直持续到2个下标指针互相越过对方
            while (list[low] <= pivot && low < high) {// 寻找第一个>pivot的元素,因为high和low在变化,所以这里也要加上条件low
                                                        // < high
                low++; // 这里不会发生下标越界,所以low < high的位置可以任意放置
            }
            while (list[high] > pivot && low < high) {// 寻找第一个≤pivot的元素
                high--;
            }
            if (high > low) {// 将2个找到的元素互换位置
                int temp = list[high];
                list[high] = list[low];
                list[low] = temp;
            }
        }

        while (high > first && list[high] > pivot) {// 将high移动到pivot应该在的位置,这个时候list[high]
                                                    // < pivot,条件必须是
            high--; // list[high] >= pivot,避免pivot=list[high],导致后面交换出现问题
        }

        if (list[high] <= pivot) {// 如果pivot没有在应该在的位置上,则将其与应该在的位置上的元素交换,并返回high
            list[first] = list[high];
            list[high] = pivot;
            return high;
        } else {
            return first;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值