Arrays 使用快速排序划分的中值规则中位数越界误差
我正在使用来自的算法选择kth元素,但在java中实现它时遇到了困难。我得到一个数组越界错误,想知道是否有人可以帮助我正确地实现这个算法Arrays 使用快速排序划分的中值规则中位数越界误差,arrays,algorithm,select,median,Arrays,Algorithm,Select,Median,我正在使用来自的算法选择kth元素,但在java中实现它时遇到了困难。我得到一个数组越界错误,想知道是否有人可以帮助我正确地实现这个算法 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 at test2.selection2(test2.java:23) at test2.select4(test2.java:16) at test2.partition2(test2.java:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at test2.selection2(test2.java:23)
at test2.select4(test2.java:16)
at test2.partition2(test2.java:55)
at test2.selection2(test2.java:27)
at test2.select4(test2.java:16)
at test2.partition2(test2.java:55)
at test2.selection2(test2.java:27)
at test2.select4(test2.java:16)
at test2.main(test2.java:11)
这些是变量的值:
N size = 10
low = 0
high = 10
k = 3
arraysize = 10
r = 2
i = 1,2,3
first = 0,5,10
last = 4,9,11
lower = 7, 33
upper = 10, 44
-pivotitem
T size = 2
low = 0
high = 2
k = 1
arraysize = 10
r = 0
high==low [0]
list is empty
因为我的数组从10开始,所以r将是2。当从pivotitem再次调用partition2时,r将为0,从而生成大小为0的数组T。然后low和high将等于0,不返回任何内容,这就是我得到错误的地方。我不知道为什么会发生这种情况,因为我的代码与书中的算法类似。您的swap方法看起来像是以索引作为参数,但您为它提供了值
list = swap (list[i], list[j], list);
这不是错误的根源,更改调用后错误仍然存在,但可能您多次出错。顺便说一句:代码到哪里去了?原来是C代码?使用&
index& pivotpoint)
这意味着调用方可以看到一个引用,即更改后的结果
你似乎用一个静态的“thepivotpoint”来解决这个问题,但是你不能用它作为参数;它只会隐藏静态成员
public static void partition2 (int[] list, int low, int high) // , int pivotpoint)
/* unchanged */
thepivotpoint = j - 1;
list = swap (mark, thepivotpoint, list);
}
它还没有完成 我还有一些其他的改进,没有解决方案,但可能有更好的基础来进一步:
- 并非所有变量都在方法的开头声明(pascal样式),以缩小它们的范围。这样就更容易对代码进行推理
- 我将参数顺序统一了一点
(int[],int,…)
- 如果。。。返回其他…李>
- 将分区2拆分为2个方法
- 添加了一种调试
的方法,该方法会触发计数器,使其在无限循环中停止show
- 删除了对我没有帮助的评论。也许你可以添加更好的评论
import java.util.Arrays; public class Pivot { static int thepivotpoint; public static void main(String[] args) { int[] list = {17, 10, 44, 7, 7, 33, 24, 10, 48, 49 }; thepivotpoint = 0; System.out.println (select4 (list, list.length, 3)); } public static int select4 (int[] list, int high, int k) { return selection2 (list, 0, high, k); // return selection2 (list, 1, high, k); } public static int selection2 (int[] list, int low, int high, int k) { if (high == low) return list[low]; partition2 (list, low, high); if (k == thepivotpoint) return list [thepivotpoint]; if (k < thepivotpoint) return selection2 (list, low, thepivotpoint - 1, k); return selection2 (list, thepivotpoint + 1, high, k); } static int count = 0; public static void show (int [] T) { for (int i : T) System.out.print (i + "\t"); System.out.println (); if (++count > 20) System.exit (1); } public static void partition2 (int[] list, int low, int high) { int arraysize = high - low; int r = (int) Math.ceil (arraysize / 5); int [] T = new int[r+1]; for (int i = 1; i <= r; i++) { int first = low + 5 * i - 5; int last = Math.min (low + 5 * i - 1, arraysize); T [i] = median (list, first, last); } show (list); approximateTheMedian (T, r, low, high, list); } public static void approximateTheMedian (int [] T, int r, int low, int high, int [] list) { int pivotitem = select4 (T, r, (r + 1) / 2); int j = low; int mark = 0; for (int i = low; i < high; i++) { if (list[i] == pivotitem) { list = swap (i, j, list); mark = j; //mark where pivotitem placed j++; } else if (list[i] < pivotitem) { list = swap (i, j, list); j++; } } thepivotpoint = j - 1; list = swap (mark, thepivotpoint, list); } public static int median (int[] list, int start, int end) { int [] copy = (int[]) list.clone (); Arrays.sort (copy); return copy [(start + end) / 2]; } public static int[] swap (int one, int two, int[] list) { int dummy = list[one]; list[one] = list[two]; list[two] = dummy; return list; } }
导入java.util.array; 公共类轴心 { 静态点到点; 公共静态void main(字符串[]args) { int[]list={17,10,44,7,7,33,24,10,48,49}; 皮点=0; System.out.println(选择4(list,list.length,3)); } 公共静态int select4(int[]列表,int高,int k) { 返回选择2(列表,0,高,k); //返回选择2(列表,1,高,k); } 公共静态整数选择2(整数[]列表,整数低位,整数高位,整数k) { 如果(高==低) 返回列表[低]; 分区2(列表、低、高); if(k==原点) 返回列表[thepivotpoint]; if(k<原点) 返回选择2(列表,低位,原点-1,k); 返回选择2(列表,原点+1,高位,k); } 静态整数计数=0; 公共静态无效显示(int[]T) { for(int i:T) System.out.print(i+“\t”); System.out.println(); 如果(++计数>20)System.exit(1); } 公共静态无效分区2(int[]列表,int低,int高) { int arraysize=高-低; int r=(int)Math.ceil(arraysize/5); int[]T=新的int[r+1];
对于(int i=1;i)来说,这是第一个快速快照:low=0,high=10-这些索引是吗?大小是然后=11,而不是10。可能是因为这个吗?…从那时起,长度=11…代码和链接消失了。奇怪的是,似乎我删除了它,但我只是恢复并修复了我的交换。但是它仍然不起作用