龙通科技笔试题之2、编写将一维数组a[]中互不相同的数按从小到大顺序重新存于一维数组a[]的程序。

dudi123456 2019-06-09 11:28:31
2、编写将一维数组a[]中互不相同的数按从小到大顺序重新存于一维数组a[]的程序。
class A{
public static void main(String[] args){
int a[]={15,7,15,6,4,3,4,6,7};
int i,j,k,low,high,mid,t;
for(i=k=1;i<a.length;i++){
low=0;
high=k-1;
while(___1_____){
mid=(low+high)/2;
if(a[mid]>=a[i]) ______2______;
else low=mid+1;
}
if(_____3_______|| a[low]!=a[i]){
t=a[i];
for(j=k-1;_____4_____;j--)
a[j+1]=a[j];
______5_____;
k++;
}
}
for(j=0;j<k;j++)
System.out.prinln(a[j]);
}
}
如上所示:填写题中五个空白,实现排序数组。
...全文
652 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
dudi123456 2019-06-22
  • 打赏
  • 举报
回复
引用 17 楼 qq_39936465 的回复:
[quote=引用 16 楼 dudi123456 的回复:] 咱们没有一个对的
是我考虑不周,但是这个思路是对的,只是没考虑到当12,12有2个相等的情况其实只要改一下就行了吧 low=i改为k就行了。 不过这个数组的元数据就被破坏了

public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a[] =  {12,12,13,14,7};
		int i, j, k, low, high, mid, t;
		for (i = k = 1; i < a.length; i++) {
			low = 0;
			high = k - 1;
			while (low < high) {
				mid = (low + high) / 2;
				if (a[mid] >= a[i])
					high = mid;
				else
					low = mid + 1;
			}
			if ((k == (a[low] < a[i] ? low = k : low)) || a[low] != a[i]) {
				t = a[i];
				for (j = k - 1; j >= low; j--)
					a[j + 1] = a[j];
				a[low] = t;
				k++;
			}
		}
		for (j = 0; j < k; j++)
			System.out.print(a[j]+" ");
	}

7 12 13 14 
[/quote] 测试了您的代码的各种情况,没有发现问题。完美! 思考了一下这句代码:k == (a[low] < a[i] ? low = k : low) 所展现的意义: 1.要解决第一次进来,相当于没有求low的值,就算a[0]<a[1]也一定会交换位置的问题。 因为第一次进来low=0;i=1;k=1. 若a[low]<a[i],那么把low=k,这时if判断k==k,一定走里面的代码。但是由于我们把low=k了,而这时k=i=1,所以里面的for循环不会 走,同时,位置交换t = a[i];.......a[low] = t; 等于没交换。k++走了。不交换正确,k++正确。 若a[low]=a[i],那么k==low一定不成立,后面的或者条件也不成立,不走if。不交换正确,不k++正确。 若a[low]>a[i],那么k==low一定不成立,但是a[low] != a[i]成立,走if,正常交换,k++。交换正确,k++正确。 2.要解决若 a[i] 的值比前面的值都大,求得的low不对的问题。 若a[low]<a[i],那么把low=k,这时if判断k==k,一定走里面的代码。但是由于我们把low=k了,而这时k的值是已排序不重复数组的长 度,low的值一定是k-1,相当于low++,得到了low的正确位置。位置交换的时候k++走了。交换正确,k++正确。 综上,其实这么写也可以 k == ( a[low] < a[i] ?++ low : 0),关键就是在low的值错误的时候,要手动改变low的值和low的值正确的时候,不要影响后面的判断:(k==0也是一定不会为真的)。所以还可以这么写:low == ( a[low] < a[i] ? low++ : -1). 不过我有一个问题:既然所有的问题都指向low的值求的不正确,那么是否我们是前面的求low的代码

 while(___1_____){
   	mid=(low+high)/2;
   	if(a[mid]>=a[i]) ______2______;
   	else low=mid+1;
  }
有毛病呢?如果一开始就能够求得正确的low,那么也不会有后面这么弯弯绕绕的代码了呀? 问题应该是真正的完美解决了,最后再提一嘴:这个面试题如果以前没有见过,真的是有人能够在面试的时候做出来吗?我!不!信!太难了。
qq_39936465 2019-06-17
  • 打赏
  • 举报
回复
就是当遇到最大值是把最大值赋值给a[k],而不是我之前的a[i]位置不变。
qq_39936465 2019-06-17
  • 打赏
  • 举报
回复
引用 16 楼 dudi123456 的回复:
咱们没有一个对的


是我考虑不周,但是这个思路是对的,只是没考虑到当12,12有2个相等的情况其实只要改一下就行了吧 low=i改为k就行了。
不过这个数组的元数据就被破坏了


public static void main(String[] args) {
// TODO Auto-generated method stub
int a[] = {12,12,13,14,7};
int i, j, k, low, high, mid, t;
for (i = k = 1; i < a.length; i++) {
low = 0;
high = k - 1;
while (low < high) {
mid = (low + high) / 2;
if (a[mid] >= a[i])
high = mid;
else
low = mid + 1;
}
if ((k == (a[low] < a[i] ? low = k : low)) || a[low] != a[i]) {
t = a[i];
for (j = k - 1; j >= low; j--)
a[j + 1] = a[j];
a[low] = t;
k++;
}
}
for (j = 0; j < k; j++)
System.out.print(a[j]+" ");
}



7 12 13 14
dudi123456 2019-06-14
  • 打赏
  • 举报
回复
引用 13 楼 qq_39936465 的回复:
没必要想你这样写的这么复杂 (k == (a[low] < a[i] ? low = i : low))这样就够了 ,如果a[i]是最大值只要for循环不执行,让low=i 就行了。

public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a[] =  { 13 , 12  ,14 , 15 , 18  ,6,  4 , 3 , 4 , 6,  7 };
		int i, j, k, low, high, mid, t;
		for (i = k = 1; i < a.length; i++) {
			low = 0;
			high = k - 1;
			while (low < high) {
				mid = (low + high) / 2;
				if (a[mid] >= a[i])
					high = mid;
				else
					low = mid + 1;
			}
			if ((k == (a[low] < a[i] ? low = i : low)) || a[low] != a[i]) {
				t = a[i];
				for (j = k - 1; j >= low; j--)
					a[j + 1] = a[j];
				a[low] = t;
				k++;
			}
		}
		for (j = 0; j < k; j++)
			System.out.print(a[j]+" ");
	}
}

3 4 6 7 12 13 14 15 18 
我擦咧,一顿分析,结果不对,用你的代码走的:

 当前a为:  
12  12  14  13  7  
 当前a为:  
12  12  14  13  7  
 当前a为:  
12  12  14  13  7  
 当前a为:  
12  12  14  13  7  
 当前a为:  
7  12  14  13  7  
7  12  
用我的代码走的:

 当前a为:  
12  12  14  13  7  
 当前a为:  
12  12  14  13  7  
 当前a为:  
14  12  14  13  7  
 当前a为:  
13  14  12  13  7  
 当前a为:  
7  13  14  12  7  
7  13  14  12  
咱们没有一个对的
dudi123456 2019-06-14
  • 打赏
  • 举报
回复
引用 14 楼 dudi123456 的回复:
[quote=引用 12 楼 qq_39936465 的回复:] [quote=引用 10 楼 dudi123456 的回复:] 您说得对,其实问题就是要在 (low == i - 1) && (a[low] < a[i]) 的条件下做到两件事: 1.不移位 2.k++ 所以我弄了一个三目运算,利用这个三目运算实现上述两个功能 : k == ((low == i - 1) && (a[low] < a[i]) ? ++low + ++k : k + 1) 。 ++low 是为了使得||后面的low==i,故a[low] != a[i]不会满足,循环跳过, ++k是为了把k值+1. 还要注意k==(。。。。)一定不要满足,即||前面的条件一定要为假 如此一来就满足题意了。 测试没问题。 不知道您觉得对不对?
虽然你程序是没问题,但是填不了空吧! 已经和填空没关系了啊 [/quote] 是有点太长了。。。 仔细分析一下,当 a[low] < a[i] 时,low一定等于i-1 这是因为我们下一步会把a[i]放到a[low]的位置上,同时把a[low]后移: 说明要移动的时候一定有 a[low] < a[i]

                t = a[i];
                for (j = k - 1; j >= low; j--)
                    a[j + 1] = a[j];
                a[low] = t;
所以这个条件(low == i - 1) && (a[low] < a[i])其实只需要写a[low] < a[i] , 然后就是 k==low = i : low 由于当a[low] < a[i]的时候呢,其实low一定等于i-1,而这时k一定等于low;所以我们把k置为i,就等同于k++;否则k==low,这个一定不成立。 综上分析,这么写:k == (a[low] < a[i] ? low = i : low) 是对的,而且也能填的下空了 不得不提一下这么写: k==low = i 它是一个判断句,但同时也是一个赋值语句,真的厉害,刚看到我还认为这个会报错,语法是错误的呢,学到了。[/quote] 不对,理解错了 应该是:k == ( low = i ) ;low=i 之后,这个表达式的值是i,然后判断k==这个表达式的值,,k的值从来没有++,k一直是原值,但是由于这个时候k确实等于i,所以会走for循环,k在里面++。但是这时low==i了,所以for循环里面 j = k - 1; j >= low 这个条件一定为假,所以for循环其实没有做任何事,t = a[i]; ..... a[low] = t;也无所谓。这才是k的值正确改变和没有发生交换的原因
dudi123456 2019-06-14
  • 打赏
  • 举报
回复
引用 12 楼 qq_39936465 的回复:
[quote=引用 10 楼 dudi123456 的回复:] 您说得对,其实问题就是要在 (low == i - 1) && (a[low] < a[i]) 的条件下做到两件事: 1.不移位 2.k++ 所以我弄了一个三目运算,利用这个三目运算实现上述两个功能 : k == ((low == i - 1) && (a[low] < a[i]) ? ++low + ++k : k + 1) 。 ++low 是为了使得||后面的low==i,故a[low] != a[i]不会满足,循环跳过, ++k是为了把k值+1. 还要注意k==(。。。。)一定不要满足,即||前面的条件一定要为假 如此一来就满足题意了。 测试没问题。 不知道您觉得对不对?
虽然你程序是没问题,但是填不了空吧! 已经和填空没关系了啊 [/quote] 是有点太长了。。。 仔细分析一下,当 a[low] < a[i] 时,low一定等于i-1 这是因为我们下一步会把a[i]放到a[low]的位置上,同时把a[low]后移: 说明要移动的时候一定有 a[low] < a[i]

                t = a[i];
                for (j = k - 1; j >= low; j--)
                    a[j + 1] = a[j];
                a[low] = t;
所以这个条件(low == i - 1) && (a[low] < a[i])其实只需要写a[low] < a[i] , 然后就是 k==low = i : low 由于当a[low] < a[i]的时候呢,其实low一定等于i-1,而这时k一定等于low;所以我们把k置为i,就等同于k++;否则k==low,这个一定不成立。 综上分析,这么写:k == (a[low] < a[i] ? low = i : low) 是对的,而且也能填的下空了 不得不提一下这么写: k==low = i 它是一个判断句,但同时也是一个赋值语句,真的厉害,刚看到我还认为这个会报错,语法是错误的呢,学到了。
qq_39936465 2019-06-13
  • 打赏
  • 举报
回复
引用 10 楼 dudi123456 的回复:
您说得对,其实问题就是要在 (low == i - 1) && (a[low] < a[i]) 的条件下做到两件事:
1.不移位
2.k++
所以我弄了一个三目运算,利用这个三目运算实现上述两个功能 :
k == ((low == i - 1) && (a[low] < a[i]) ? ++low + ++k : k + 1) 。
++low 是为了使得||后面的low==i,故a[low] != a[i]不会满足,循环跳过,
++k是为了把k值+1.
还要注意k==(。。。。)一定不要满足,即||前面的条件一定要为假
如此一来就满足题意了。
测试没问题。
不知道您觉得对不对?


虽然你程序是没问题,但是填不了空吧! 已经和填空没关系了啊
dudi123456 2019-06-13
  • 打赏
  • 举报
回复
我想到了正确的写法!!
package hashMap;

public class A {

	// 2、编写将一维数组a[]中互不相同的数按从小到大顺序重新存于一维数组a[]的程序。
	// 二分排序(插入排序的加强)
	public static void main(String[] args) {
		int a[] = { 13 , 12  ,14 , 15 , 18  ,6,  4 , 3 , 4 , 6,  7 };
		printa(a);
		int i, j, k, low, high, mid, t;
		// i 数组下标
		// j 插入时后移用到的下标
		// k 已排序的元素个数
		// low 二分法的区域下界下标
		// high 二分法的区域上界下标
		// mid 上下界的一半的下标
		// t 用于在后移元素时保存将要被覆盖的那个值
		for (i = k = 1; i < a.length; i++) {// 从第1个开始,因为数组第一个元素默认已排
			low = 0;
			high = k - 1;// 为什么?从0 到k-1下标的是已排序的数组
			while (low < high) {
				mid = (low + high) / 2;
				if (a[mid] >= a[i])// 取得中间的那个数,比当前的数大
					high = mid;// 取前半部分
				else
					low = mid + 1;// 取后半部分
			}
			// 换位置。 什么情况下不需要换位置?
			// 1.low的位置就在i之前的一个 =集合A
			// 且
			// 2.当前a[i],已经等于啊a[low] ,如 1,2,3,【a[i]=3】,...=集合B
			// a&&B
			// 所以要交换位置的时候就是!(A&&B)
			// !A||!B
			// 用集合可以和明显看出来

			// 若求得的low=i-1,不让他走循环,但是要让k++
			if (k == ((low == i - 1) && (a[low] < a[i]) ? ++low + ++k : k + 1) || a[low] != a[i]) {
				t = a[i];
				for (j = k - 1; j >= low; j--)// 把所有元素后移一个位置
					a[j + 1] = a[j];
				a[low] = t;
				k++;
			}
			printa(a);
		}
		for (j = 0; j < k; j++)// 最后已排序数据的长度,其实就是a.length
			System.out.print(a[j] + "  ");
	}

	private static void printa(int[] a) {
		System.out.println(" 当前a为:  ");
		for (int i = 0; i < a.length; i++) {
			System.out.print(a[i] + "  ");
		}
		System.out.println();
	}

}
运行结果:

 当前a为:  
13  12  14  15  18  6  4  3  4  6  7  
 当前a为:  
12  13  14  15  18  6  4  3  4  6  7  
 当前a为:  
12  13  14  15  18  6  4  3  4  6  7  
 当前a为:  
12  13  14  15  18  6  4  3  4  6  7  
 当前a为:  
12  13  14  15  18  6  4  3  4  6  7  
 当前a为:  
6  12  13  14  15  18  4  3  4  6  7  
 当前a为:  
4  6  12  13  14  15  18  3  4  6  7  
 当前a为:  
3  4  6  12  13  14  15  18  4  6  7  
 当前a为:  
3  4  6  12  13  14  15  18  4  6  7  
 当前a为:  
3  4  6  12  13  14  15  18  4  6  7  
 当前a为:  
3  4  6  7  12  13  14  15  18  6  7  
3  4  6  7  12  13  14  15  18  
您说得对,其实问题就是要在 (low == i - 1) && (a[low] < a[i]) 的条件下做到两件事: 1.不移位 2.k++ 所以我弄了一个三目运算,利用这个三目运算实现上述两个功能 : k == ((low == i - 1) && (a[low] < a[i]) ? ++low + ++k : k + 1) 。 ++low 是为了使得||后面的low==i,故a[low] != a[i]不会满足,循环跳过, ++k是为了把k值+1. 还要注意k==(。。。。)一定不要满足,即||前面的条件一定要为假 如此一来就满足题意了。 测试没问题。 不知道您觉得对不对?
dudi123456 2019-06-13
  • 打赏
  • 举报
回复
引用 9 楼 dudi123456 的回复:
[quote=引用 8 楼 qq_39936465 的回复:] [quote=引用 6 楼 dudi123456 的回复:] 前几个空应该填的有错误,考虑不周到。说不定还要用到老长老长的三目运算。
前面都是正常的2分算法,应该不会有太大的差别,主要是判断插入最大值上有问题 if(_____3_______|| a[low]!=a[i])如何利用这句判断把后面的最大值插入在最后。[/quote] 第一次进来,不论a[0] a[1]的大小铁定交换也是有问题的吧?[/quote] 像我上面那种写法,真的不是正常人能想出来的,其实我是在另一个程序里找到的灵感:龙通科技面试题之:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人。这种写法,确实很精妙。
qq_39936465 2019-06-13
  • 打赏
  • 举报
回复
没必要想你这样写的这么复杂

(k == (a[low] < a[i] ? low = i : low))这样就够了 ,如果a[i]是最大值只要for循环不执行,让low=i 就行了。


public static void main(String[] args) {
// TODO Auto-generated method stub
int a[] = { 13 , 12 ,14 , 15 , 18 ,6, 4 , 3 , 4 , 6, 7 };
int i, j, k, low, high, mid, t;
for (i = k = 1; i < a.length; i++) {
low = 0;
high = k - 1;
while (low < high) {
mid = (low + high) / 2;
if (a[mid] >= a[i])
high = mid;
else
low = mid + 1;
}
if ((k == (a[low] < a[i] ? low = i : low)) || a[low] != a[i]) {
t = a[i];
for (j = k - 1; j >= low; j--)
a[j + 1] = a[j];
a[low] = t;
k++;
}
}
for (j = 0; j < k; j++)
System.out.print(a[j]+" ");
}
}


3 4 6 7 12 13 14 15 18
dudi123456 2019-06-12
  • 打赏
  • 举报
回复
前几个空应该填的有错误,考虑不周到。说不定还要用到老长老长的三目运算。
dudi123456 2019-06-12
  • 打赏
  • 举报
回复
引用 4 楼 qq_39936465 的回复:
[quote=引用 3 楼 dudi123456 的回复:] 多了这一个判断:if (a[high]!=a[i] || a[low] != a[i]) 会不会导致k++不走了。一旦k++不走了,下面的输出会错,上面的k-1,也不对。您看对不对?
不会不走,就是这个程序本身有问题,如果第一个不是最大会出现问题。 [/quote] 会不会是我们没有想到正确的填法,现在的问题有两个: 1.不管0号位和1号位谁大,由于第一次进来 low = 0; high=i-1=0;故不满足 low < high 所以一定会跳过while循环(),进而一定有a[low] != a[i](i这时=1),且由于是||,所以一定会交换位置。(相等时也可以理解为交换了位置。暂不论k); 2.一旦出现这样的顺序 当前a为: 13 12 14 15 18 6 4 3 4 6 7 注意:14>12 14>13 当前a为: 12 13 14 15 18 6 4 3 4 6 7 第一步,铁定交换 当前a为: 12 14 13 15 18 6 4 3 4 6 7 这一步错了!逻辑不对:由于14大于前面已排序的所有数,故找不到正确的low 也就是说,我们应该做到:第一步不应该铁定交换,当一个数大于前面所有已排序数时,能正确把这个数放到所有已排序数的末尾。 至于这句:if (a[high]!=a[i] || a[low] != a[i]) 其实是为了去重,保证数组不重复,满足题意,是需要的。(当这个数已经排过了,我就不管他了,已排的数k也不应该++)。 但是我有一点不同的意见:low和high到这里了之后应该是一定相等的,所以这个空填 a[high]!=a[i] 估计不对,有些重复。 您有什么好的意见吗?
dudi123456 2019-06-12
  • 打赏
  • 举报
回复
引用 8 楼 qq_39936465 的回复:
[quote=引用 6 楼 dudi123456 的回复:] 前几个空应该填的有错误,考虑不周到。说不定还要用到老长老长的三目运算。
前面都是正常的2分算法,应该不会有太大的差别,主要是判断插入最大值上有问题 if(_____3_______|| a[low]!=a[i])如何利用这句判断把后面的最大值插入在最后。[/quote] 第一次进来,不论a[0] a[1]的大小铁定交换也是有问题的吧?
qq_39936465 2019-06-12
  • 打赏
  • 举报
回复
引用 6 楼 dudi123456 的回复:
前几个空应该填的有错误,考虑不周到。说不定还要用到老长老长的三目运算。
前面都是正常的2分算法,应该不会有太大的差别,主要是判断插入最大值上有问题 if(_____3_______|| a[low]!=a[i])如何利用这句判断把后面的最大值插入在最后。
qq_39936465 2019-06-12
  • 打赏
  • 举报
回复
引用 5 楼 dudi123456 的回复:
会不会是我们没有想到正确的填法,现在的问题有两个: 1.不管0号位和1号位谁大,由于第一次进来 low = 0; high=i-1=0;故不满足 low < high 所以一定会跳过while循环(),进而一定有a[low] != a[i](i这时=1),且由于是||,所以一定会交换位置。(相等时也可以理解为交换了位置。暂不论k); 2.一旦出现这样的顺序 当前a为: 13 12 14 15 18 6 4 3 4 6 7 注意:14>12 14>13 当前a为: 12 13 14 15 18 6 4 3 4 6 7 第一步,铁定交换 当前a为: 12 14 13 15 18 6 4 3 4 6 7 这一步错了!逻辑不对:由于14大于前面已排序的所有数,故找不到正确的low 也就是说,我们应该做到:第一步不应该铁定交换,当一个数大于前面所有已排序数时,能正确把这个数放到所有已排序数的末尾。 至于这句:if (a[high]!=a[i] || a[low] != a[i]) 其实是为了去重,保证数组不重复,满足题意,是需要的。(当这个数已经排过了,我就不管他了,已排的数k也不应该++)。 但是我有一点不同的意见:low和high到这里了之后应该是一定相等的,所以这个空填 a[high]!=a[i] 估计不对,有些重复。 您有什么好的意见吗?
如果值比前面的都大只要k+1就行了,但是我一直没想到怎么把k+1加入判断语句中,然后跳出if。
qq_39936465 2019-06-11
  • 打赏
  • 举报
回复
引用 3 楼 dudi123456 的回复:
多了这一个判断:if (a[high]!=a[i] || a[low] != a[i]) 会不会导致k++不走了。一旦k++不走了,下面的输出会错,上面的k-1,也不对。您看对不对?
不会不走,就是这个程序本身有问题,如果第一个不是最大会出现问题。
qq_39936465 2019-06-10
  • 打赏
  • 举报
回复
引用 楼主 dudi123456 的回复:
2、编写将一维数组a[]中互不相同的数按从小到大顺序重新存于一维数组a[]的程序。 如上所示:填写题中五个空白,实现排序数组。

public class A {

	public static void main(String[] args) {
		int a[] = {15,7,15,6,4,3,4,6,7};
		int i, j, k, low, high, mid, t;
		for (i = k = 1; i < a.length; i++) {
			low = 0;
			high = k - 1;
			while (low < high) {
				mid = (low + high) / 2;
				if (a[mid] >= a[i])
					high = mid ;
				else
					low = mid + 1;
			}
			
			if (a[high]!=a[i] || a[low] != a[i]) {
				t = a[i];
				for (j = k -1; j >= low; j--)
					a[j + 1] = a[j];
				a[low] = t;
				k++;
			}
		}
		for (j = 0; j < k; j++)
			System.out.print(a[j] + "  ");
	}
}
运行结果:

3  4  6  7  15  
dudi123456 2019-06-10
  • 打赏
  • 举报
回复
引用 2 楼 qq_39936465 的回复:
[quote=引用 楼主 dudi123456 的回复:] 2、编写将一维数组a[]中互不相同的数按从小到大顺序重新存于一维数组a[]的程序。 如上所示:填写题中五个空白,实现排序数组。

public class A {

	public static void main(String[] args) {
		int a[] = {15,7,15,6,4,3,4,6,7};
		int i, j, k, low, high, mid, t;
		for (i = k = 1; i < a.length; i++) {
			low = 0;
			high = k - 1;
			while (low < high) {
				mid = (low + high) / 2;
				if (a[mid] >= a[i])
					high = mid ;
				else
					low = mid + 1;
			}
			
			if (a[high]!=a[i] || a[low] != a[i]) {
				t = a[i];
				for (j = k -1; j >= low; j--)
					a[j + 1] = a[j];
				a[low] = t;
				k++;
			}
		}
		for (j = 0; j < k; j++)
			System.out.print(a[j] + "  ");
	}
}
运行结果:

3  4  6  7  15  
[/quote] 多了这一个判断:if (a[high]!=a[i] || a[low] != a[i]) 会不会导致k++不走了。一旦k++不走了,下面的输出会错,上面的k-1,也不对。您看对不对?
dudi123456 2019-06-09
  • 打赏
  • 举报
回复
package hashMap;

public class A {

	// 2、编写将一维数组a[]中互不相同的数按从小到大顺序重新存于一维数组a[]的程序。
	// 二分排序(插入排序的加强)
	public static void main(String[] args) {
		int a[] = {15,7,15,6,4,3,4,6,7};
		printa(a);
		int i, j, k, low, high, mid, t;
		// i 数组下标
		// j 插入时后移用到的下标
		// k 已排序的元素个数
		// low
		// high
		// mid
		// t 用于在后移元素时保存将要被覆盖的那个值
		for (i = k = 1; i < a.length; i++) {// 从第1个开始,因为数组第一个元素默认已排
			low = 0;
			high = k - 1;//为什么?从0 到k-1下标的是已排序的数组
			while (low < high) {
				mid = (low + high) / 2;
				if (a[mid] >= a[i])//取得中间的那个数,比当前的数大
					high = mid ;//取前半部分
				else
					low = mid + 1;
			}
			//换位置。 什么情况下不需要换位置?
			//1.low的位置就在i之前的一个    =集合A
			//且
			//2.当前a[i],已经等于啊a[low] ,如  1,2,3,【a[i]=3】,...=集合B
			//a&&B
			//所以要交换位置的时候就是!(A&&B)
			//!A||!B
			//用集合可以和明显看出来
			//if (low!=i-1 || a[low] != a[i]) {
				t = a[i];
				for (j = k -1; j >= low; j--)// 把所有元素后移一个位置
					a[j + 1] = a[j];
				a[low] = t;
				k++;
			//}
			printa(a);
		}
		for (j = 0; j < k; j++)// 最后已排序数据的长度,其实就是a.length
			System.out.print(a[j] + "  ");
	}

	private static void printa(int[] a) {
		System.out.println(" 当前a为:  ");
		for (int i = 0; i < a.length; i++) {
			System.out.print(a[i] + "  ");
		}
		System.out.println();
	}

}
题目好像有问题,其中第三个空应该是不需要的,因为不论怎样都要移动位置,否则不走k++会导致k的值不正确。

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧