我想了解Insertionsort。我听说我可以通过哨兵改进它。
这是我没有哨兵的代码:
public static int[] insertionSort(int[] sortieren) {
int temp;
for (int i = 1; i < sortieren.length; i++) {
temp = sortieren[i];
int j = i;
while (j > 0 && sortieren[j - 1] > temp) {
sortieren[j] = sortieren[j - 1];
j--;
}
sortieren[j] = temp;
}
return sortieren;
}
我正在尝试了解在哪种情况下我可以获得ArrayIndexOutOfBounds异常。你能帮助我理解为什么有一个改进代码所需的Sentinel,以及我必须输入的地方吗?我会说我必须在数组的左边缘放置一个Integer.MIN_Value,但我不确定,因为我没有看到它用完数组的情况。
如果您能帮我理解Insertionsort中哨兵的用法,我将不胜感激。
使用Sentinel ......
public void insertionSort(int[] array) {
int temp;
int arraySentinel[] = new int[array.length+1];
for(int i = 0; i < array.length; i++){
arraySentinel[i+1] = array[i];
}
arraySentinel[0] = Integer.MIN_VALUE;
for (int i = 1; i < arraySentinel.length; i++) {
temp = arraySentinel[i];
int j = i;
/**
* Stabil weil sortieren[j-1] > temp!
* Wäre nicht stabil wenn >=!
*/
while (arraySentinel[j - 1] > temp) {
arraySentinel[j] = arraySentinel[j - 1];
j--;
}
arraySentinel[j] = temp;
}
for (int i = 1; i < arraySentinel.length; i++){
array[i-1] = arraySentinel[i];
}
}
答案 0 :(得分:1)
静态Sentinel将是一个非常低的值,它将作为数组的第一个元素放置。在数组[0]中。这样做的好处是不会在代码中检查条件“j&gt; 0”。
添加了j&gt; 0条件,以便程序不会给出ArrayIndexOutOfBounds异常。通过在数组[0]处添加填充元素,并从数组[1 .... n]运行循环,我们节省了检查j> 0条件的开销。
请注意,无症状,它无法影响插入排序的复杂性。
编辑:您修改后的实施是正确的。我认为你很困惑,因为现在你必须再次填满整个阵列,这将花费额外的θ(n)时间。所以你担心添加哨兵实际上会让它变慢。但是,您需要了解这是Java的问题。 Java数组具有不可变的大小,因此您需要创建一个新数组。这不是算法的了望。算法与语言无关。如果您将使用其他语言具有可变数组大小规定或使用Java的List,则可以在O(1)时间内添加sentinel。在这种情况下,生成的程序会更快。
答案 1 :(得分:1)
您不需要制作更大尺寸的新阵列。
只需运行一个数组,找到最小元素并将其移至第0位。
现在这个元素作为哨兵工作,你可以在不进行边框检查的情况下对数组的其余部分进行排序。