java数据结构排序之希尔排序实现

早上鲜血来潮想写个希尔排序算法,发现发生了错误,一直不解,最初写的代码如下所示:

static void shellSort(int[] dataList,int dk){
		System.out.println("dk="+dk);
		for (int i = dk; i < dataList.length; i++) {
			
			int flag=i,temp=dataList[flag];
			for (int j = i; (j-dk) >=0; j-=dk) {
				<span style="color:#ff0000;">if(dataList[j] >= dataList[j-dk]){</span>
					break;
				}else{
					dataList[j] = dataList[j-dk];
					flag=j-dk;
				}
			}
			dataList[flag] = temp;
		}
		print(dataList);
	}

想调用它试试,却发现

static void print(int[] dataList){
		for (int j = 0; j < dataList.length; j++) {
				System.out.print(dataList[j]+"  ");
		}
		System.out.println();
	}
	
	public static void main(String[] args) {
		int[] dataList = {13,65,97,76,38,27,49,10,0};
		for (int i = (dataList.length/2); i >0 ; i/=2) {
			shellSort(dataList, i);
		}
		
	}

错误原因在于红色代码注释处的判断条件,希尔排序的规则,应该以待插入的元素为依据,假如待插入的元素大小为temp,所在位置为k,增量为dk,则应该把所有满足k-=dk且k-=dk所在位置元素大于temp的元素右移dk个位置,但是上述代码却不是以temp为主来判断大小,而是以k-dk和k所在位置的元素为依据,这样最终插入temp元素的位置可能不是最合理的位置,就可能会出现如图片中显示的错误。


正确的希尔排序如下所示

正确代码1:

static void shellSort(int[] dataList,int dk){
		System.out.println("dk="+dk);
		for (int i = dk; i < dataList.length; i++) {
			
			int flag=i,temp=dataList[flag];
			for (int j = i; (j-dk) >=0; j-=dk) {
				<span style="color:#ff0000;">if(temp >= dataList[j-dk]){</span>
					break;
				}else{
					dataList[j] = dataList[j-dk];
					flag=j-dk;
				}
			}
			dataList[flag] = temp;
		}
		print(dataList);
	}
正确代码2:

static void shellSort(int[] dataList,int dk){
		System.out.println("dk="+dk);
		for (int i = dk; i < dataList.length; i++) {
			
			int flag=i,temp=dataList[flag];
			for (int j = i-dk; j >=0; j-=dk) {
				System.out.println(j);
				<span style="color:#ff0000;">if(dataList[j]<= temp){</span>
					break;
				}else{
					dataList[j+dk] = dataList[j];
					flag=j;
				}
			}
			dataList[flag] = temp;
		}
		print(dataList);
	}
注意代码红色注释处,所有的判断应与temp元素比较。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值