在Java中实现合并排序:仅零
作为一个教育过程,我正在尝试用Java实现一些在int数组上工作的排序算法。我现在试着对合并排序进行思考。昨天我得到了一个非常远的结果,得到了一个大小正确的数组,但只包含零。今天我从新开始,现在我被困在同一点上^^ 这是我的密码:在Java中实现合并排序:仅零,java,algorithm,sorting,mergesort,Java,Algorithm,Sorting,Mergesort,作为一个教育过程,我正在尝试用Java实现一些在int数组上工作的排序算法。我现在试着对合并排序进行思考。昨天我得到了一个非常远的结果,得到了一个大小正确的数组,但只包含零。今天我从新开始,现在我被困在同一点上^^ 这是我的密码: public static int[] mergeSort(int[] array) { if (array.length < 2) { return array; } int left = 0; int righ
public static int[] mergeSort(int[] array) {
if (array.length < 2) {
return array;
}
int left = 0;
int right = array.length;
int p = array.length / 2;
int[] lArray = Arrays.copyOfRange(array, left, p);
int[] rArray = Arrays.copyOfRange(array, p, right);
lArray = mergeSort(lArray);
rArray = mergeSort(rArray);
return merge(lArray, rArray);
}
private static int[] merge(int[] lArray, int[] rArray) {
int[] result = new int[lArray.length + rArray.length];
int idx = 0;
int rIdx = 0;
int lIdx = 0;
while (lIdx < lArray.length - 1 && rIdx < rArray.length - 1) {
if (lArray[lIdx] < rArray[rIdx]) {
result[idx] = lArray[lIdx];
lIdx++;
} else if (lArray[lIdx] >= rArray[rIdx]) {
result[idx] = rArray[rIdx];
rIdx++;
}
idx++;
}
if (lIdx < (lArray.length - 1)) {
result[idx] = lArray[lIdx + 1];
} else if (rIdx < (rArray.length - 1)) {
result[idx] = rArray[rIdx + 1];
}
return result;
}
公共静态int[]合并排序(int[]数组){
if(array.length<2){
返回数组;
}
int左=0;
int right=array.length;
int p=array.length/2;
int[]lArray=Arrays.copyOfRange(数组,左,p);
int[]rArray=Arrays.copyOfRange(array,p,right);
lArray=合并排序(lArray);
rArray=合并排序(rArray);
返回合并(lArray、rArray);
}
私有静态int[]合并(int[]lArray,int[]rArray){
int[]结果=新int[lArray.length+rArray.length];
int-idx=0;
int-rIdx=0;
int lIdx=0;
而(lIdx=rArray[rIdx]){
结果[idx]=rArray[rIdx];
rIdx++;
}
idx++;
}
如果(lIdx<(lArray.length-1)){
结果[idx]=lArray[lIdx+1];
}否则如果(rIdx<(rArray.length-1)){
结果[idx]=rArray[rIdx+1];
}
返回结果;
}
我认为它的风格和可读性都很好。那么,你们所有的算法和Java都崩溃了,我遗漏了什么?调试指向merge方法,但我不能完全确定它,所以我按原样发布了它
提前谢谢 if(lIdx<(lArray.length-1)){
if (lIdx < (lArray.length - 1)) {
result[idx] = lArray[lIdx + 1];
} else if (rIdx < (rArray.length - 1)) {
result[idx] = rArray[rIdx + 1];
}
结果[idx]=lArray[lIdx+1];
}否则如果(rIdx<(rArray.length-1)){
结果[idx]=rArray[rIdx+1];
}
这部分有点奇怪。为什么只将剩余的一个元素复制到结果数组中?您应该将lArray或rArray中的所有剩余元素复制到结果中。使用“while”而不是“if”。我发现您的
合并方法中存在两个问题:
首先,while循环忽略左数组和右数组的最后一个元素。你应该改变
while (lIdx < lArray.length - 1 && rIdx < rArray.length - 1)
while(lIdx
到
while(lIdx
其次,在该while循环之后,还需要两个while循环来添加左数组的尾部或右数组的尾部。相反,您只添加一个元素
替换
if (lIdx < (lArray.length - 1)) {
result[idx] = lArray[lIdx + 1];
} else if (rIdx < (rArray.length - 1)) {
result[idx] = rArray[rIdx + 1];
}
if(lIdx<(lArray.length-1)){
结果[idx]=lArray[lIdx+1];
}否则如果(rIdx<(rArray.length-1)){
结果[idx]=rArray[rIdx+1];
}
与
while(lIdx
给你
public class MergeSort {
public static int[] mergeSort(int[] array) {
if (array.length < 2) {
return array;
}
int left = 0;
int right = array.length;
int p = array.length / 2;
int[] lArray = Arrays.copyOfRange(array, left, p);
int[] rArray = Arrays.copyOfRange(array, p, right);
//printArray(lArray); seems ok
//printArray(rArray); seems ok
lArray = mergeSort(lArray);
rArray = mergeSort(rArray);
return merge(lArray, rArray);
}
private static int[] merge(int[] lArray, int[] rArray) {
/*System.out.println("Ive got");
printArray(lArray);
printArray(rArray); seems ok*/
int[] result = new int[lArray.length + rArray.length];
int index = 0;
int rightIndex = 0;
int leftIndex = 0;
while (leftIndex < lArray.length && rightIndex < rArray.length) { //TODO
if (lArray[leftIndex] < rArray[rightIndex]) {
result[index] = lArray[leftIndex];
leftIndex++;
index++;
//} else if (lArray[leftIndex] >= rArray[rightIndex]) { // You don't have to check it!!!
} else {
System.out.println("2 left index " + leftIndex + " index " + index);
result[index] = rArray[rightIndex];
rightIndex++;
index++;
}
}
while (leftIndex < (lArray.length)) { // TODO
result[index] = lArray[leftIndex];
index++;
leftIndex++;
}
while (rightIndex < (rArray.length)) { // TODO
result[index] = rArray[rightIndex];
index++;
rightIndex++;
}
System.out.println("Returning ");
printArray(result);
return result;
}
public static void printArray(int[] arr) {
for (int i : arr)
System.out.print(i + " ");
System.out.println();
}
public static void main(String[] args) {
int[] arr = {2, 1, 3, 4, 0, -1};
printArray(arr);
arr = mergeSort(arr);
printArray(arr);
}
}
公共类合并排序{
公共静态int[]合并排序(int[]数组){
if(array.length<2){
返回数组;
}
int左=0;
int right=array.length;
int p=array.length/2;
int[]lArray=Arrays.copyOfRange(数组,左,p);
int[]rArray=Arrays.copyOfRange(array,p,right);
//打印阵列(lArray);看起来还可以
//打印阵列(rArray);看起来还可以
lArray=合并排序(lArray);
rArray=合并排序(rArray);
返回合并(lArray、rArray);
}
私有静态int[]合并(int[]lArray,int[]rArray){
/*System.out.println(“我得到”);
打印阵列(lArray);
打印阵列(rArray);看起来还可以*/
int[]结果=新int[lArray.length+rArray.length];
int指数=0;
int rightIndex=0;
int leftIndex=0;
而(leftIndex=rArray[rightIndex]){//您不必检查它!!!
}否则{
System.out.println(“2左索引”+左索引+“索引”+索引);
结果[索引]=rArray[右索引];
rightIndex++;
索引++;
}
}
而(leftIndex<(lArray.length)){//TODO
结果[索引]=lArray[左索引];
索引++;
leftIndex++;
}
而(rightIndex<(rArray.length)){//TODO
结果[索引]=rArray[右索引];
索引++;
rightIndex++;
}
系统输出打印项次(“返回”);
打印阵列(结果);
返回结果;
}
公共静态void打印数组(int[]arr){
用于(int i:arr)
系统输出打印(i+“”);
System.out.println();
}
公共静态void main(字符串[]args){
int[]arr={2,1,3,4,0,-1};
打印阵列(arr);
arr=合并排序(arr);
打印阵列(arr);
}
}
错误的地方用//TODO
标记。您是否只是尝试用一个短数组一步一步地调试这个问题,以找到零的来源?调试器是你最好的朋友,你不能用易读的名字来考虑可读的东西,比如<代码> LIDX,<代码> RIDX,<代码> p>代码>我总是试图调试它,按照你的建议去做——正如我所说的,我看到了我正在获得合并方法错误的提示,但是我不确定确切的位置。哦,关于一个变量名p,你是对的。我坚持使用教授给我的伪代码,但忘了对此进行评论。然而,我发现过长的语句比明显的缩写更影响可读性在第二段中,添加idx++so:result[idx++]=rArray[rIdx++];结果[idx++]=lArray[lIdx++]@劳尔圭,谢谢。错过了为什么第二个while循环?长度差只能是一个,由调用方法的逻辑决定。如果merge
是公共的,我同意,人们可能会尝试使用任意长度的数组来调用它,但是
while (lIdx < lArray.length) {
result[idx++] = lArray[lIdx++];
}
while (rIdx < rArray.length) {
result[idx++] = rArray[rIdx++];
}
public class MergeSort {
public static int[] mergeSort(int[] array) {
if (array.length < 2) {
return array;
}
int left = 0;
int right = array.length;
int p = array.length / 2;
int[] lArray = Arrays.copyOfRange(array, left, p);
int[] rArray = Arrays.copyOfRange(array, p, right);
//printArray(lArray); seems ok
//printArray(rArray); seems ok
lArray = mergeSort(lArray);
rArray = mergeSort(rArray);
return merge(lArray, rArray);
}
private static int[] merge(int[] lArray, int[] rArray) {
/*System.out.println("Ive got");
printArray(lArray);
printArray(rArray); seems ok*/
int[] result = new int[lArray.length + rArray.length];
int index = 0;
int rightIndex = 0;
int leftIndex = 0;
while (leftIndex < lArray.length && rightIndex < rArray.length) { //TODO
if (lArray[leftIndex] < rArray[rightIndex]) {
result[index] = lArray[leftIndex];
leftIndex++;
index++;
//} else if (lArray[leftIndex] >= rArray[rightIndex]) { // You don't have to check it!!!
} else {
System.out.println("2 left index " + leftIndex + " index " + index);
result[index] = rArray[rightIndex];
rightIndex++;
index++;
}
}
while (leftIndex < (lArray.length)) { // TODO
result[index] = lArray[leftIndex];
index++;
leftIndex++;
}
while (rightIndex < (rArray.length)) { // TODO
result[index] = rArray[rightIndex];
index++;
rightIndex++;
}
System.out.println("Returning ");
printArray(result);
return result;
}
public static void printArray(int[] arr) {
for (int i : arr)
System.out.print(i + " ");
System.out.println();
}
public static void main(String[] args) {
int[] arr = {2, 1, 3, 4, 0, -1};
printArray(arr);
arr = mergeSort(arr);
printArray(arr);
}
}