为什么这种合并排序会产生错误的结果?

时间:2014-02-19 21:18:00

标签: java arrays sorting

我的任务是使用用户填充的int数组合并两个数组,我们必须假设用户最多有10000个输入,并且用户输入一个负数来停止。然后将数组从最小到最大排序并打印出来。最初我认为这很容易但是当我完成后,我开始得到输出,如:

Enter the values for the first array, up to 10000 values, enter a negative number to quit: 1  
3  
5  
-1  
Enter the values for the second array, up to 10000 values, enter a negative number to quit  
2   
4  
6  
-1  
First Array:  
1   
3   
5  
Second Array:   
2  
4   
6   
Merged Array:  
6 1 2 3 4 5     

正如你所看到的,这六个是不合适的,我不知道如何解决它。这是源代码,我已经包含了大量的评论,因为我真的希望你们能够帮助我发挥最大的能力。如果可以使用相同的确切技术而不在代码中实现新技术和方法,请执行此操作。我知道java中的方法可以在一行中完成所有这些,但它是在更基本的级别上进行的赋值。

import java.util.Scanner;

public class Merge

{


    public static void main(String [] args)    
    {
        Scanner scan = new Scanner(System.in);

    int [] first = new int[10000];          //first array, assume 10k inputs max
    int [] second = new int[10000];         //first array, assume 10k inputs max

    boolean legal = true; //WILL IMPLIMENT LATER


    int end = 0; // set how many elements to put in my "both" array
    int end2 = 0;// set how many elements to put in my "both" array


    System.out.print("Enter the values for the first array, up to 10000 values, enter a negative number to quit");
    //get values
    for(int i = 0; i<first.length; i++)
    {
          first[i] = scan.nextInt(); //fill first with user input

          if(first[i] <0) //if negative number, stop loop
          {
            end = i; //get position of end of user input
            break;
          }
    }

    System.out.println("Enter the values for the second array, up to 10000 values, enter a negative number to quit");

    for(int i = 0; i<second.length; i++) //exact same as the first get values loop
    {
      second[i] = scan.nextInt();

      if(second[i] <0)
      {
        end2 = i;
        break;
      }
    }

    System.out.print("First Array:\n");

    for(int i = 0; i<first.length; i++) //print first array
    {
      if(i == end) //this prevents from printing thousands of zeros, only prints values that user inputed
        break;
      System.out.println(first[i] + " ");
    }


    System.out.print("Second Array:\n"); 

    for(int i = 0; i<second.length; i++) //same as printing first array 
    {
          if(i == end2)
            break;
          System.out.println(second[i] + " ");
    }

    int [] both = new int[(end)+(end2)]; //instanciate an int array to hold only inputted values from first[] and second[]
    int [] bothF = new int[(end)+(end2)]; //this is for my simple sorter algotithm loop

    for(int i = 0; i<both.length; i++) //fill both with the first array that was filled
    {
      both[i] = first[i];
    }

    int temp = end; // see below
    for(int i = 0;i<both.length; i++) //fill array with the second array that was filled(starting from the end of the first array so that the first set is not overwritten
    {
      if(temp<both.length){ //this prevents an out of bounds
      both[temp] = second[i];

        temp++;}
    }

    //simple sorting algorithm
    for(int d = both.length -1;d>=0;d--)
    {    
          for(int i = 0; i<both.length; i++)
           {
                if(both[d]<both[i])
                {
                      bothF[d] = both[d];
                      both[d] = both[i];
                      both[i] = bothF[d];          
                }      
          }
    }

    System.out.println("Merged Array:"); //print the results
    for(int i = 0; i<both.length; i++)
    {
        System.out.print(both[i] + " ");

    }

    //System.out.println("ERROR: Array not in correct order");    
}

4 个答案:

答案 0 :(得分:3)

您的排序算法有问题。

它类似于选择排序,因为你拿两个元素并交换它们,如果它们不合适的话。但是,您应该在以下情况下停止比较:当索引d小于索引i时,基于arr[d] > arr[i]的比较和交换不再有效。

内部循环应以i=d终止。

你的逻辑是这样的:

在第d个循环中,d+1和右侧的元素被正确排序(较大的数字)。这在开头就是如此,因为在最右边的元素的右边有正确排序的0个元素。

在每个外部循环上(使用d计数器),将d-th largest element slot与每个未排序的元素进行比较,并在另一个元素较大时进行交换。

这足以对数组进行排序,但如果您开始将d-th largest element slot与已排序的元素进行比较,那么您最终会在插槽中使用更大的数字。因此,内部循环应在到达d时终止。

答案 1 :(得分:1)

当然,你可以这样做

for (int i = 0; i < end; i++) {
    both[i] = first[i];
}
for (int i = 0; i < end2; i++) {
    both[i + end] = second[i];
}

// simple sorting algorithm
for (int d = both.length - 1; d >= 0; d--) {
    for (int i = 0; i < d; i++) {
        if (both[i] > both[d]) {
            int t = both[d];
            both[d] = both[i];
            both[i] = t;
        }
    }
}

输出 -

Enter the values for the first array, up to 10000 values, enter a negative number to quit3
5
-1
Enter the values for the second array, up to 10000 values, enter a negative number to quit
2
4
6
-1
First Array:
3 
5 
Second Array: 
2 
4 
6
-1 
Merged Array:
2 3 4 5 6 

答案 2 :(得分:0)

首先,我将从一些建议开始:

  1. 1.将end1和end2作为数组长度的初始值。
  2. 打印部分 - 而不是打破循环 - 循环直到i ==结束(如果它没有被第一部分改变,它将保持数组长度)。
  3. 一个建议是在用户输入上使用“while”语句来执行阅读部分(它看起来更干净然后打破循环 - 但它可以像你一样做)。
  4. 尝试使用更多功能。
  5. 现在主要的事情 - 为什么不将两个数组中的数字插入到连接数组中以保持它们的排序?

    指导:

    • 为每个阵列保留一个标记。
    • 迭代新的连接数组如果arr1 [marker1]&gt; ARR2 [MARKER2] 将arr2 [marker2]插入当前位置的关节数组。 并将1添加到marker2。和相反的。

      (不要忘记选择相同的情况)。

    这可以实现,因为数组首先被排序。

    玩得开心!

答案 3 :(得分:0)

我猜你有一种反向的“选择排序”算法。我创建了一个运行代码的类,并在每次交换后打印出输出。以下代码与您在应用程序中添加print的相同。

for(int d = both.length -1;d>=0;d--)
 {    
  for(int i = 0; i<both.length; i++)
   {
    if(both[d]<both[i])
     {
      int temp = both[d];
      both[d] = both[i];
      both[i] = temp;
      printArray(both);
     }
  }
}

当我们在一个示例数组上运行时,我们得到了这个输出

[9, 8, 7, 6]= 
-> 6879
-> 6789
-> 6798
-> 6978
-> 9678

该算法在两次交换后实际上得到了正确的答案,但随后开始将它们混乱到错误的顺序。问题是内部for循环结束参数。当您运行外循环一次后,您可以确定最大数字是最终的。 'd'在这里3,它每次遇到它时都会换出更大的数字。第一个循环中的if子句比较是6-9(交换),9-8,9-7,9-9。到目前为止一切都很好。

潜在问题出现在第二次迭代中,'d'为2.数组现在为[6,8,7,9],比较为7-6,7-8(与结果交换[6,7,8, 9]),8-8,8-9(交换!!)导致[6,7,9,8]。最后一次交换是有问题的。我们知道最大的数字已经在最后一个位置,但我们仍然比较它。随着整个内循环的每一次过去,它总会找到最大的数字(以及所有其他大于已经存在的[d]的数字)并将其交换到某个错误的位置。

正如我们所知,在外循环的一次迭代之后,最大数字将是最后一个,我们不应该在第二次迭代中与它进行比较。你有点锁定数组中的9并且只尝试对其余数据进行排序,在这种情况下[6,8,7]其中d = 3,值为7.因此,你的内部循环for(int i = 0; i<both.length; i++)变为{{1 }}。作为额外的奖励,您知道在最后一次迭代for(int i = 0; i<=d; i++)中,因此其中的代码i==d将永远不会成立,您可以进一步将循环增强为if(both[d]<both[i])。< / p>

在你的算法中,你总是在外循环的四次迭代中在内循环中进行四次比较,这意味着总共有16次比较。如果我们使用for(int i = 0; i<d; i++),我们将在外循环的第一次迭代中在内循环中进行三次比较,然后是两次,然后是一次。这使它总共进行了六次比较。

对不起,如果太漫无边际,只想彻底。