插入排序及归并排序java代码实现及详细注释

public static void main(String[] args) {
		// 定义无序数组
		Integer[] arr = new Integer[]{12,14,56,89,11,66,99,3,6,34};
		// 插入排序前
		System.out.println("插入排序前");
		Arrays.asList(arr).forEach(e -> System.out.print(e + "  "));
		System.out.println("\r\n"+"插入排序后");
		// 插入排序后:
		Arrays.asList(insertionSort(arr)).forEach(e -> System.out.print(e + "  "));
		
		// 定义无序数组
		Integer[] arg = new Integer[]{12,14,56,89,11,66,99,3,6,34};
		// 归并排序前
		System.out.println("\r\n"+ "归并排序前");
		Arrays.asList(arg).forEach(e -> System.out.print(e + "  "));
		// 归并排序后
		System.out.println("\r\n"+"归并排序后");
		Arrays.asList(mergeSort(arg)).forEach(e-> System.out.print(e + "  "));
	}
	
	/**
	 * 插入排序  时间复杂度O(n^2)
	 * 	    思路    (1)当前元素的前面元素均为有序
	 *        (2)要插入时,从当前元素的左边开始往前找(从后往前找),比当前元素大的元素均往右移一个位置
	 * @param arr
	 * @return
	 */
	private static Integer[] insertionSort(Integer[] arr){
		long start = new Date().getTime();
		for (int i = 1; i < arr.length; i++) {
			if (arr[i-1] > arr[i]) {  // 如果 i比前一位小   进行插入操作    
				int temp = arr[i];    // 记录arr[i]的值
				int j = i;            // 记录下角标
				while (j > 0 && temp < arr[j-1]) {  
					arr[j] = arr[j-1];				// 前一位数向后挪一位	
					j--;
				}
				arr[j] = temp;
			}
		}
		long end = new Date().getTime();
		System.out.println("插入排序运行时间  :" + (end - start) + " 毫秒");
		return arr;
	}
	
	/**
	 * 归并排序   时间复杂度 O(n log n)
	 * 	     思路   Divide:  把长度为n的输入序列分成两个长度为n/2的子序列。
     *        Conquer: 对这两个子序列分别采用归并排序。      
     *        Combine: 将两个排序好的子序列合并成一个最终的排序序列
	 * @param arg
	 * @return
	 */
	private static Integer[] mergeSort(Integer[] arg){
		long start = new Date().getTime();
		Integer[] temp = new Integer[arg.length];
		sort(arg, 0, arg.length);
		long end = new Date().getTime();
		System.out.println("程序运行时间  :" + (end - start) + " 毫秒");
		return arg;
	}

	/**
	 * "归" 递归拆分数组 
	 * 
	 * @param numbers
	 * @param pos
	 * @param end
	 */
    public static void sort(Integer[] numbers,Integer pos,Integer end){

        if ((end - pos) > 1) {                // 递归出口 当数组不可再分时 跳出递归
            int offset = (end + pos) >> 1;    // 分成2个数组
            sort(numbers, pos, offset);		  // 分别取前半部分和后半部分数组进行递归排序	
            sort(numbers, offset, end);		  //  向下递归直到找到叶子节点
            merge(numbers, pos, offset, end);  // 合并俩个排好序的数组
        }
    }
    /**
     * "并" 将排好序的数组合并
     * 
     * @param numbers
     * @param pos
     * @param offset
     * @param end
     */
    public static void merge(Integer[] numbers,Integer pos,Integer offset,Integer end){

    	Integer[] array1 = new Integer[offset - pos];           // array1 为numbers数组前半部分
    	Integer[] array2 = new Integer[end - offset];			// array2 为后半部分
        System.arraycopy(numbers, pos, array1, 0, array1.length);      // 从数组源numbers复制数组到 array1
        System.arraycopy(numbers, offset, array2, 0, array2.length);   // 从数组源numbers复制数组到 array2

        for (int i = pos, j = 0, k = 0; i < end ; i++) {
            if (j == array1.length) {                                  // 俩个数组有一个数组元素耗尽(都比较过排好序后)时
                System.arraycopy(array2, k, numbers, i, array2.length - k);    // 将另一个数组复制到numbers数组中
                break;
            }
            if (k == array2.length) {
                System.arraycopy(array1, j, numbers, i, array1.length - j);   
                break;
            }
            if (array1[j] <= array2[k]) {			// 后半部分数组元素跟前半部分比较 
                numbers[i] = array1[j++];			// 如果前半部分元素小于或等于后半部分元素    numbers数组元素位置不变 
            } else {								// j++ 继续判断 前半部分后一位元素 跟后半部分比较
            	numbers[i] = array2[k++];			// 否则 numbers数组元素 i位元素替换为 后半部分元素 
            }										// k++ 继续判断 后半部分后一位元素 跟前半部分比较
        }
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值