归并排序 - 非递归实现

import java.util.Arrays; /** * @title MergeSortByNonRecursion * @description 归并排序,非递归实现 * author zzw * version 1.0.0 * create 2024/10/23 22:17 **/ public class MergeSortByNonRecursion { public static void main(String[] args) { int[] nums = {5, 1, 1, 2, 0, 0}; new MergeSortByNonRecursion().sortArray(nums); System.out.println(Arrays.toString(nums)); } public int[] sortArray(int[] nums) { sort(nums); return nums; } /** * 归并排序,非递归处理<br/> * <ol> * <li>每次将相邻的两个有序数组进行合并</li> * <li>先从只有一个节点的数组开始(一个节点默认有序,无需做其他处理),从做向右合并</li> * <li>将数组处理完一遍后,将节点个数增大一倍,将合并好的子数组再进行合并</li> * </ol> * * @param arr 排序数组 */ public static void sort(int[] arr) { // 每次用来合并的子数组中的元素个数,每次增加一倍 for (int i = 1; i < arr.length; i <<= 1) { // 默认左侧数据的起始节点从0开始 int leftIndex = 0; // 计算出中间节点 int mid = leftIndex + i - 1; // 只有中间节点小于数组长度减一的时候,才能保证左右两侧数组都存在数据,这样才需要进行数组的合并 while (mid < arr.length - 1) { // 计算出右侧子数组的最后一个节点下标 // 该下标取中间节点加子数组长度个数 和 总数组长度的最小值,避免数组越界 int right = Math.min((mid + i), arr.length - 1); // 进行数组合并 merge(arr, leftIndex, mid, right); // 计算下一组需要合并的子数组的左侧数组起始位置 leftIndex = right + 1; // 计算下一组需要合并的子数组的左侧数组终止位置 // 这里计算用于判断是否还有数据数据放入右侧数组进行合并 mid = leftIndex + i - 1; } } } /** * 合并两个有序数组 * * @param arr 两个有序数组所在的有序数据 * @param left 左侧有序数据在arr数组中的起始位置 * @param mid 左侧有序数组在arr数组中的终点位置 * @param right 右侧有序数组在arr数组中的终点位置,起始位置在mid+1处 */ public static void merge(int[] arr, int left, int mid, int right) { // 使用一个临时数据存放合并后的数据 int[] tmp = new int[right - left + 1]; // 临时数据数据合并到的下标 int i = 0; // 左侧有序数据处理到的位置 int lIndex = left; // 右侧有序数据处理到的位置 int rIndex = mid + 1; // 比较左、右两侧的有序数组,谁的值小,将谁放到临时数组中, // 然后将临时数组、取值的哪个数组的处理下标向后移动 // 直到左、右两侧的数组有一个处理完,停止此次处理 while (lIndex <= mid && rIndex <= right) { tmp[i++] = arr[lIndex] <= arr[rIndex] ? arr[lIndex++] : arr[rIndex++]; } // 如果左侧的有序数组没有处理完,将左侧数组的剩余数据放入临时数组中 while (lIndex <= mid) { tmp[i++] = arr[lIndex++]; } // 如果右侧的有序数组没有处理完,将右侧数组的剩余数据放入临时数组中 while (rIndex <= right) { tmp[i++] = arr[rIndex++]; } // 将临时数组中的数据放回原来的数据中 for (int j = 0; j < i; j++) { arr[j + left] = tmp[j]; } } }
上一篇:深入剖析:神经网络的结构与功能解读


下一篇:MYSQL数据库SQL+DQL