早上鲜血来潮想写个希尔排序算法,发现发生了错误,一直不解,最初写的代码如下所示:
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元素比较。