排序算法(未完工)

本文详细介绍了八种经典的排序算法:冒泡排序、堆排序、插入排序、归并排序、快速排序、基数排序、选择排序和希尔排序。通过代码实现,展示了每种排序算法的工作原理和效率特点,为理解和应用这些排序算法提供了清晰的指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

排序算法

冒泡

public class bubble {

    public void bubbleSort (int[] arr) {

        if (arr.length < 2) {
            return;
        }

        // 外层循环代表循环 (冒泡) 次数
        // 每完成一次冒泡就会有一个最小的数浮到数列顶端
        for (int i = 0; i < arr.length - 1; i++) {
            // 内层循环代表两两比较 (每完成一次冒泡就可以相应的减少一次比较)
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j, j + 1);
                }
            }
        }
    }

    private void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

}

堆排序

public class heap {

    // 堆排序
    public static int[] heapSort(int[] arr) {
        int len = arr.length;
        if (len < 2) {
            return null;
        }

        // 构造大根堆
        buildMaxHeap(arr, len);

        // 不断地交换堆顶元素和当前堆中的最后一个元素, 并且不断地调整堆
        // 那么就可以得到一个从尾到头的递减序列, 从正向来看就是一个递增序列
        for (int i = len - 1; i > 0; i--) {
            // 交换堆顶元素和当前堆中的最后一个元素
            swap(arr, 0, i);
            // 调整堆
            len--;
            heapify(arr, 0, len);
        }

        return arr;
    }

    // 初始数据构造大根堆 (下沉)
    private static void buildMaxHeap(int[] arr, int len) {
        // 从最后一个非叶子结点开始,依次向前
        // 当一个节点比其子节点小,则需要不断地向下进行比较和交换操作
        for (int i = (int) Math.floor(len / 2); i >= 0; i--) {
            heapify(arr, i, len);
        }
    }

    // 调整堆中以第 i 个节点为 root 的子树
    private static void heapify(int[] arr, int i, int len) {
        // 第 i 个节点的左孩子
        int left = 2 * i + 1;
        // 第 i 个节点的右孩子
        int right = 2 * i + 2;

        // 一个节点如果有两个子节点,应当与两个子节点中最大那个节点进行交换
        int largest = i;
        if (left < len && arr[left] > arr[largest]) {
            largest = left;
        }
        if (right < len && arr[right] > arr[largest]) {
            largest = right;
        }
        if (largest != i) {
            swap(arr, i, largest);
            // 继续调整堆中以 largest 为 root 的子树
            heapify(arr, largest, len);
        }
    }

    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

}

插入排序

public class insert {

    public void insertSort(int[] arr) {
        if (arr.length < 2) {
            return;
        }

        // 从下标为 1 的元素开始选择合适的位置插入, 依次将待排序列中的元素插入到有序序列中
        for (int i = 1; i < arr.length; i ++) {
            // 记录要进行插入的数据
            int temp = arr[i];
            // 有序序列的最后一个元素下标
            int j = i - 1;
            // 将要插入的元素插入到有序序列中
            while (j >= 0 && temp < arr[j]) {
                // 有序序列中的元素右移 arr[j] -> arr[j+1]
                arr[j + 1] = arr[j];
                j--;
            }

            // 插入数据
            if (j + 1 != i) {
                arr[j + 1] = temp;
            }
        }
    }

}

归并排序

public class merge {

    public void mergeSort(int[] arr, int L, int R) {

        if (L == R) {
            return;
        }else {
            //取中间数进行拆分
            int M = (L + R) / 2;
            //左边的数不断进行拆分
            mergeSort(arr, L, M);
            //右边的数不断进行拆分
            mergeSort(arr, M + 1, R);

            //合并
            merge(arr, L, M + 1, R);

        }
    }

    public void merge(int[] arr, int L, int M, int R) {

        int[] leftArray = new int[M - L];
        int[] rightArray = new int[R - M + 1];

        for (int i = L; i < M; i++) {
            leftArray[i - L] = arr[i];
        }
        for (int i = M; i <= R; i++) {
            rightArray[i - M] = arr[i];
        }

        int i =0, j = 0;
        //arr的第一个元素
        int k = L;

        //比较两个数组的值,哪个小,就往数组上放
        while (i <leftArray.length && j < rightArray.length) {

            if (leftArray[i] < rightArray[j]) {
                arr[k] = leftArray[i];
                i++;
                k++;
            }else {
                arr[k] =rightArray[j];
                j++;
                k++;
            }
        }

        while (i < leftArray.length) {
            arr[k] = leftArray[i];
            i++;
            k++;
        }
        while (j < rightArray.length) {
            arr[k] = rightArray[j];
            k++;
            j++;
        }

    }


}

快速排序

public class quick {

    public void quickSort(int[] arr, int L, int R) {

        int i = L;
        int j = R;

        //支点
        int pivot = arr[(L + R) / 2];

        //左右两端进行扫描,只要两端还没有交替,就一直扫描
        while (i <= j) {

            //寻找比支点大的数
            while (pivot > arr[i]) {
                i++;
            }
            //寻找比支点小的数
            while (pivot < arr[j]) {
                j--;
            }

            if (i <= j) {
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
                i++;
                j--;
            }

        }
        //上面第一个while保证了第一趟排序支点的左边比支点小,支点的右边比支点大了

        //左边排序
        if (L < j) {
            quickSort(arr, L, j);
        }

        //右边排序
        if (i < R) {
            quickSort(arr, i ,R);
        }
    }

}

奇数排序

public class radix {

    public void radixSort(int[] arr) {
        int max = findMax(arr, 0, arr.length - 1);

        for (int i = 1; max / i > 0; i = i * 10) {

            int[][] buckets = new int[arr.length][10];

            for (int j = 0; j < arr.length; j++) {
                int num = (arr[j] / i) % 10;
                buckets[j][num] = arr[j];
            }

            int k = 0;

            for (int j = 0; j < 10; j++) {
                for (int l = 0; l < arr.length; l++) {
                    if (buckets[l][j] != 0) {
                        arr[k++] = buckets[l][j];
                    }
                }
            }

        }
    }

    public int findMax(int[] arr, int L, int R) {
        if (L == R) {
            return arr[L];
        }else {
            int a = arr[L];
            int b = findMax(arr, L + 1, R);//找出整体的最大值

            if (a > b) {
                return a;
            }else {
                return b;
            }
        }
    }

}

选择排序

public class select {

    public void selectionSort(int[] arr) {
        if (arr.length < 2) {
            return;
        }

        // 一共需要经过 arr.length - 1 轮的比较
        for (int i = 0; i < arr.length - 1; i++) {
            // 找到待排序列中的最小元素
            int min = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[min]) {
                    // 记录目前能找到的最小元素的下标
                    min = j;
                }
            }
            // 将未排序序列中的最小元素存放到已排序序列的最后
            if (i != min) {
                swap(arr, i, min);
            }
        }
    }

    private void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

}

希尔排序

public class shell {

    public void shellSort(int[] arr) {
        if (arr.length < 2) {
            return;
        }

        // 步长(增量), 每次减半
        for (int step = arr.length / 2; step >= 1; step /= 2) {
            // 从下标为 1 的元素开始选择合适的位置插入, 依次将代排序列中的元素插入到有序序列中
            for (int i = step; i < arr.length; i ++) {
                // 记录要进行插入的数据
                int temp = arr[i];
                // 有序序列的最后一个元素的下标
                int j = i - step;
                // 将要插入的元素插入到有序序列中
                while (j >= 0 && temp < arr[j]) {
                    // 有序序列中的元素右移 arr[j] -> arr[j+step]
                    arr[j + step] = arr[j];
                    j -= step;
                }

                // 插入数据
                if (j + step != i) {
                    arr[j + step] = temp;
                }
            }
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值