简体   繁体   English

Java Quicksort算法无法正常工作

[英]Java Quicksort Algorithm doesnt work properly

I have two Arraylists, which should be sort descending due to the values in the second Arraylist(which is type double). 我有两个Arraylist,由于第二个Arraylist(类型为double)中的值,它们应该按降序排列。 Basically the values of the first Arraylist are not regarded, but the elements in the first Arraylist map to the ones in the second one, so both Arrays should get sortet due to the values in Arraylist2. 基本上不考虑第一个Arraylist的值,但是第一个Arraylist中的元素映射到第二个Arraylist中的元素,因此由于Arraylist2中的值,两个Array都应进行排序。 (I hope this is more or less clear) (我希望这或多或少是清楚的)

Problem: 问题:

Somehow when I print out the values of Arraylist2 (with the double values) after beeing sorted they are totally not sorted, but have a different sequence than before sorting. 不知何故,当我对beeing进行排序后打印出Arraylist2的值(带有双精度值)时,它们完全没有排序,但是排序顺序与排序前不同。 I also wrote some debug system.outs, which shows me the algoritm is running, but I have no idea, why it won`t sort correctly, I hope somebody can see where the problem is. 我还写了一些debug system.outs,它向我展示了算法正在运行,但是我不知道为什么它不能正确排序,我希望有人可以看到问题所在。

Code: 码:

Call + Outputcode: 通话+输出代码:

            String str = "";
        // DEBUG //
        for(int k = 0; k < test.size(); k++) {
            str += " " + test.get(k);   
        }
        System.out.println(str);
        System.out.println("------------------------------------------------------------------/r/n");
        sort(items, test, 0 ,(test.size() -1));
        String str2 = "";
        for(int k = 0; k < test.size(); k++) {
            str2 += " " + test.get(k);  
        }
        System.out.println(str2);
        // DEBUG //

Quicksort algoritm: Quicksort算法:

public void sort(ArrayList<Item> items, ArrayList<Double> nutzen, int l, int r) {
        if(l < r) {
            double pivot = nutzen.get(r);
            int p = partition(items, nutzen, l, r, pivot);
            sort(items, nutzen, l, p-1);
            sort(items, nutzen, p+1, r);
        }
    }

    private int partition(ArrayList<Item> items, ArrayList<Double> nutzen, int l, int r, double pivot) {
        int i = l;
        int j = r-1;
        do {
            do {
                i = i + 1;
            } while(i < r && nutzen.get(i) > pivot);
            do {
                j = j - 1;
            } while(j > l && nutzen.get(i) < l);
            if(i < j) {
                // Tausche Daten
                double tmp  = nutzen.get(i);
                Item tmp2 = items.get(i);
                nutzen.set(i, nutzen.get(j));
                nutzen.set(j, tmp);
                items.set(i, items.get(j));
                items.set(j, tmp2);
            }
        } while(i < j); 
        if (nutzen.get(i) > pivot) {
            double tmp  = nutzen.get(i);
            Item tmp2 = items.get(i);
            nutzen.set(i, nutzen.get(r));
            nutzen.set(r, tmp);
            items.set(i, items.get(r));
            items.set(r, tmp2);
        }
        return i;       
    }

Sample Output: (first is the unsorted Arraylist, second the sorted one) 示例输出:(第一个是未排序的Arraylist,第二个是已排序的Arraylist)

 0.22540250447227192 0.5289855072463768 0.3245742092457421 0.35105028644175684 0.3773755656108597 0.2041172365666434 0.4091826437941473 0.33037437282902354 0.4383735705209657 0.28473648186173856 0.3422330097087379 0.25703446095478977 0.3373493975903614 0.2701873935264055 0.3221397891448653 0.34912891986062716 0.3018603018603019 0.31361550229474755 0.35785288270377735 0.27435456110154904 0.22781065088757396 0.27684563758389263 0.21881770349736923 0.4226451927769644 0.24628854206318995 0.3256219991270188 0.3844096293465801 0.3178254051228437 0.398093508851566 0.3544702638834187 0.20851528384279475 0.4041025641025641 0.21713772992373262 0.26014028667276606 0.3591307662981319 0.23153252480705622 0.27023319615912206 0.24333719582850522 0.29892573563755254 0.31568998109640833 0.27108784176847006 0.34125412541254124 0.279090113735783 0.3737704918032787 0.3326703132769766 0.22776967930029154 0.22143195827406353 0.27614293221229635 0.22866611433305717 0.533879374534624 0.28534031413612565 0.20782003213711836 0.21262837580829214 0.2137904468412943 0.2898398529797847 0.24622641509433962 0.3927108927108927 0.26053042121684866 0.3005334914048607 0.23183297180043383 0.24539571926331508 0.3479899497487437 0.4193054136874362 0.31155589123867067 0.31771595900439237 0.3897529734675206 0.3561643835616438 0.31221719457013575 0.477299880525687 0.2683881064162754 0.30484160191273163 0.20526154787396758 0.2362366474938373 0.3485633537447009 0.24390243902439024 0.2618308766485648 0.382782475019216 0.23864915572232645 0.466403162055336 0.31514030218933087 0.3074433656957929 0.3438485804416404 0.28774928774928776 0.29548816568047337 0.34277286135693213 0.5334967320261438 0.32756539235412474 0.2945334590009425 0.20973389355742297 0.25292242295430395 0.2336989640463132 0.328060522696011 0.4326647564469914 0.30530226274907124 0.3326499231163506 0.3077194219245682 0.2322235922729141 0.25569544364508395 0.3788049605411499 0.2476489028213166
------------------------------------------------------------------
 0.22540250447227192 0.5289855072463768 0.466403162055336 0.4383735705209657 0.3897529734675206 0.4193054136874362 0.4226451927769644 0.29548816568047337 0.3479899497487437 0.3438485804416404 0.477299880525687 0.3561643835616438 0.4041025641025641 0.3326703132769766 0.3844096293465801 0.4091826437941473 0.34277286135693213 0.398093508851566 0.3485633537447009 0.3927108927108927 0.4326647564469914 0.3005334914048607 0.28534031413612565 0.31155589123867067 0.31771595900439237 0.31221719457013575 0.30484160191273163 0.3074433656957929 0.31514030218933087 0.5334967320261438 0.32756539235412474 0.2898398529797847 0.25292242295430395 0.28774928774928776 0.533879374534624 0.2945334590009425 0.20973389355742297 0.27614293221229635 0.26053042121684866 0.2683881064162754 0.3737704918032787 0.279090113735783 0.34125412541254124 0.27108784176847006 0.31568998109640833 0.29892573563755254 0.2336989640463132 0.27023319615912206 0.328060522696011 0.3591307662981319 0.26014028667276606 0.30530226274907124 0.3544702638834187 0.3178254051228437 0.3256219991270188 0.3326499231163506 0.3077194219245682 0.27684563758389263 0.2322235922729141 0.27435456110154904 0.35785288270377735 0.31361550229474755 0.3018603018603019 0.34912891986062716 0.3221397891448653 0.2701873935264055 0.3373493975903614 0.25703446095478977 0.3422330097087379 0.28473648186173856 0.33037437282902354 0.25569544364508395 0.3773755656108597 0.35105028644175684 0.3245742092457421 0.2618308766485648 0.382782475019216 0.23864915572232645 0.24390243902439024 0.2362366474938373 0.20526154787396758 0.24539571926331508 0.23183297180043383 0.24622641509433962 0.2137904468412943 0.21262837580829214 0.20782003213711836 0.22866611433305717 0.22143195827406353 0.22776967930029154 0.24333719582850522 0.23153252480705622 0.21713772992373262 0.20851528384279475 0.24628854206318995 0.21881770349736923 0.22781065088757396 0.2041172365666434 0.3788049605411499 0.2476489028213166

It has been a long time since I codified sorting algorithms (oh, the joys of complete APIs) but this strikes me as odd 自从我编排排序算法以来已经很长时间了(哦,完整API的乐趣),但这让我感到奇怪

       } while(j > l && nutzen.get(i) < l);

Wouldn't it better be 会不会更好

       } while(j > l && nutzen.get(i) < pivot);

Anyway, an advice. 无论如何,一个建议。 Instead of trying to sort 10 numbers and just reporting the exit, try with 3 or 4 and debug more seriously the inner workings of your code (at each step, which pivot is chosen, what are the resulting sublists, etc.). 不要尝试对10个数字进行排序,而只是报告退出情况,请尝试使用3或4并更认真地调试代码的内部工作原理(在每个步骤中,选择哪个枢轴,产生什么子列表,等等)。

I'm just starting out, so I haven't really looked at quicksort before, but I think I got it working. 我才刚刚起步,所以我以前从未真正研究过quicksort,但我认为我可以使用它。 Just needed to tweak the 4 lines that I commented. 只需调整我评论的4行。 Also, I changed l to left, r to right, i to a and j to z, to make it a little easier for me to keep track of. 另外,我将l更改为左,将r更改为右,将i更改为a,将j更改为z,以便于跟踪。 As I said, I'm still a noob, in my first year as a comp sci major, so I can't comment on how good the implementation is. 就像我说的那样,我在学习Comp Sci专业的第一年仍然是个菜鸟,所以我无法评论实现的良好程度。 It seemed like a good problem for me to work on and try to learn a little bit. 对于我来说,努力学习一点点似乎是一个好问题。 Hope it helps you out some without being too "here's the answer"-ish. 希望它可以帮助您解决一些问题,而不必太“这就是答案”。

The changes: 变化:

  1. Offset the left and right counters further "outside" by 1 to account for them getting incremented and decremented before the comparison. 将左计数器和右计数器进一步“外”偏移1,以说明它们在比较之前会递增和递减。 Didn't seem to be parsing the entire range the way it was. 似乎并没有按原样解析整个范围。 Could have changed the inner do..while loops to while loops for same effect. 可以将内部do..while循环更改为while循环以达到相同的效果。
  2. Changed l to pivot . l更改为pivot You were comparing a value and an index. 您正在比较一个值和一个索引。 i was correct, so I figure that was just an oops. i是正确的,所以我认为这只是个糟糕。
  3. Changed if (nutzen.get(a) > pivot) to if (nutzen.get(a) < pivot) . if (nutzen.get(a) > pivot)更改为if (nutzen.get(a) < pivot) At this point I would need to spend more time figuring out the why, and I have other things that need doing. 在这一点上,我需要花更多的时间弄清楚原因,还有其他需要做的事情。 All I know is that it didn't work the other way, heh. 我所知道的是,它没有其他作用,嘿。

I didn't go crazy testing it out, but it does seem to work. 我并没有疯狂地对其进行测试,但是它似乎确实有效。 I copied about 6 of your sample values and tried them out, and it worked. 我复制了大约6个样本值,并对其进行了尝试,然后它起作用了。 Good luck! 祝好运!

private static int partition(ArrayList<Double> items, ArrayList<Double> nutzen, int left, int right, double pivot) {
    int a = left-1; //offset to account for do..while incrementing prior to comparison
    int z = right; //offset to account for do..while decrementing prior to comparison
    do {
        do {
            a++;
        } while(a < right && nutzen.get(a) > pivot);

        do {
            z--;
        } while(z > left && nutzen.get(z) < pivot); //compare to pivot, not index

        if(a < z) {
            double tmp  = nutzen.get(a);
            Double tmp2 = items.get(a);
            nutzen.set(a, nutzen.get(z));
            nutzen.set(z, tmp);
            items.set(a, items.get(z));
            items.set(z, tmp2);
        }
    } while(a < z);

    if (nutzen.get(a) < pivot) {  //changed > to <
        double tmp  = nutzen.get(a);
        Double tmp2 = items.get(a);
        nutzen.set(a, nutzen.get(right));
        nutzen.set(right, tmp);
        items.set(a, items.get(right));
        items.set(right, tmp2);
    }
    return a;       
}

.22540250447227192 0.5289855072463768 0.3245742092457421 0.35105028644175684 0.3773755656108597 0.2041172365666434
------------------------------------------------------------------
0.5289855072463768 0.3773755656108597 0.35105028644175684 0.3245742092457421 0.22540250447227192 0.2041172365666434

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM