Java面试题多思路解析--有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中

题目:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。

思路分析:将一个数字插入按要求插入到一个数组中,怎样找到这个数字的的位置是关键。

针对这一题目,我整理了三种解决方案,以下是源代码:

import java.util.Scanner;

public class InsertNumber {
	public static void main(String[] args) {
		int[] arr = { 10, 20, 30, 40, 50};
		int[] arrchange = new int[arr.length + 1];

		System.out.print("before change:  ");
		for (int i = 0; i < arr.length; i++) {
			System.out.print("  " + arr[i]);
		}
		System.out.println();

		System.out.println("Input a number:  ");
		Scanner scanner = new Scanner(System.in);
		int number = scanner.nextInt();

		// 冒泡排序的思路
		arrchange = insort1(arr, number);
		System.out.print("changed:  ");
		for (int i = 0; i < arrchange.length; i++) {
			System.out.print("  " + arrchange[i]);
		}

		// 插入排序的思路
//		arrchange = insort2(arr, number);
//		System.out.print("changed:  ");
//		for (int i = 0; i < arrchange.length; i++) {
//			System.out.print("  " + arrchange[i]);
//		}

		// 二分法的思路
//		for (int i = 0; i < arr.length; i++) {
//			arrchange[i] = arr[i];
//		}
//		
//		int location = insort3(arrchange, number);
//
//		for (int i = arrchange.length - 1; i > location; i--) {
//			arrchange[i] = arrchange[i - 1];
//		}
//
//		arrchange[location] = number;
//
//		System.out.print("changed:  ");
//		for (int i = 0; i < arrchange.length; i++) {
//			System.out.print("  " + arrchange[i]);
//		}

	}

	public static int[] insort1(int[] arr, int number) {
		int[] arrchange = new int[arr.length + 1];
		
		//将源数组复制到新的数组里,新数组最后一个元素为需要插入的数字
		for (int i = 0; i < arr.length; i++) {
			arrchange[i] = arr[i];
		}
		arrchange[arr.length] = number;
		
		//类似进行冒泡排序的最后一轮
		for (int i = arr.length; i > 0;i--) {
			if (arrchange[i] < arrchange[i - 1]) {
				int temp = arrchange[i];
				arrchange[i] = arrchange[i - 1];
				arrchange[i - 1] = temp;
			}

		}
		return arrchange;
	}

	public static int[] insort2(int[] arr, int number) {
		int[] arrchange = new int[arr.length + 1];

		for (int i = 0; i < arr.length; i++) {
			arrchange[i] = arr[i];
		}

		int i, j;

		for (i = 0; i < arrchange.length; i++) {
			if (arrchange[i] > number) { // 找到插入位置
				for (j = arrchange.length - 1; j > i; j--) {
					arrchange[j] = arrchange[j - 1]; // 后边元素依次向后移动一位
				}
				arrchange[i] = number; // 插入
				break;
			}
		}

		if (arrchange.length == i) { // 若待插之数大于所有数字,直接插到最后
			arrchange[i - 1] = number;
		}

		return arrchange;
	}

	public static int insort3(int[] arrchange, int number) {
		int low = 0;
		int high = arrchange.length - 1;
		int mid = (low + high) / 2;

		if (number > arrchange[high - 1]) {  //判断是否大于原数组最后一个元素
			return high;
		} else if (number < arrchange[0]) {  //判断是否小于原数组的第一个元素
			return 0;
		} else {
			while (low != high) {
				if(number == arrchange[mid]) {   //判断是否等于查找中间的元素
					break;
				}else if(1 == high-low) {    
					break;
				}else if(number < arrchange[mid]) {  
					high = mid;
					mid = (low + high) / 2;
				}else {
					low = mid;
					mid = (low + high) / 2;
				}
		
			}

			return mid+1;
		}

	}

}


下面分别对这三种思路进行分析:

一、冒泡排序的思路

因为已知数组是排好序的,这和冒泡排序进行最后轮排序是一样的。所以第一步,将已知数组和需要插入的数字放到一个新的数组里,且把需要插入的数字放到新的数组的 最后一位。

<span style="white-space:pre">	</span>//将源数组复制到新的数组里,新数组最后一个元素为需要插入的数字
		for (int i = 0; i < arr.length; i++) {
			arrchange[i] = arr[i];
		}
		arrchange[arr.length] = number;
然后进行冒泡排序,将最后一个数字放到合适的位置。

<span style="white-space:pre">	</span>//类似进行冒泡排序的最后一轮
		for (int i = arr.length; i > 0;i--) {
			if (arrchange[i] < arrchange[i - 1]) {
				int temp = arrchange[i];
				arrchange[i] = arrchange[i - 1];
				arrchange[i - 1] = temp;
			}

		}


二、插入排序的思路

这种思路,较为容易理解。拿着需要插入的数字,和原数组的每一个数字进行比较,满足大小条件,即可确定位置,然后插入数字。

需要注意的,最后如果被插入的数字大于原数组的所有的元素,那就把数字放到最后一位。


三、二分法的思路。

1、找出中间的那个值,判断插入值是否等于中值;

2、若等于,查找结束;若不等,如果二分查找的区间长度为1,则查找结束;

3、否则根据大小关系,继续按照1、2进行查找。

【关于返回值为什么是 mid+1 ,而不是mid 】

举个例字说明一下:

数组a[4] = {2, 4, 7, 9}   a[0]=2, a[1]=4, a[2]=7, a[3]=9。

新数组b[5]={2, 4, 7, 9, 0}

若插入值为5,   返回值应为2

第一轮:low=0, high=4, mid=2, a[mid]=7 > 5

第二轮:low=0, high=2, mid=1, a[1]=4 < 5

第三轮:low=1, high=2, mid=1, 满足查找完成条件,退出

此时mid = 1, 故返回值为mid+1。




  • 11
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值