这个划分算法,是不是整体就是错的呀 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nnegier

这个划分算法,是不是整体就是错的呀

  •  
  •   nnegier 2019 年 8 月 8 日 3346 次点击
    这是一个创建于 2450 天前的主题,其中的信息可能已经有所发展或是发生改变。
    public class Test { static int[] theArray = {25,6,5,88,56,989,41,12,34,65}; public static void main(String[] args) { partionIt(0, theArray.length-1, 88); for (int i = 0; i < theArray.length; i++) { System.out.print(theArray[i]+" "); } System.out.println(); } public static int partionIt(int left,int right,int pivot) { int leftPtr = left - 1; int rightPtr = right + 1; while (true) { while (leftPtr<right&&theArray[++leftPtr]<pivot) ; while (rightPtr>left&&theArray[--rightPtr]>pivot) ; if (leftPtr>=rightPtr) { break; }else { swap(leftPtr, rightPtr); } } return leftPtr; } public static void swap(int index1,int index2) { int temp = theArray[index1]; theArray[index1] = theArray[index2]; theArray[index2] = temp; } } 

    我选的比较值是 88,划分的意思就是小的在一边,大的在一边。

    这是输出结果:

    25 6 5 65 56 34 41 12 989 88 

    很明显正确的结果是 989 应该在 88 的右边。

    我知道出现这个错误的原因,是因为里面第一个 while 就找到了 88,然后就和第二个 while 找到的最右边那个小于 88 的交换了,然后就再也没有比较它了,所以 88 就一直在最右边了。

    这个算法是在《 Java 数据结构和算法》上看到的,代码就这样,一点没有变啊,我刚刚还确认了一下。当然比较值 pivot 换成最大值右边的数值比如 41,这个算法还是运行良好的。但是书上也没有特别指明呀。

    所以,这个算法做划分本身是错误的?

    求解

    第 1 条附言    2019 年 8 月 9 日

    改成这样即可

     public static int partionIt(int left,int right,int pivot) { int leftPtr = left; int rightPtr = right; while (true) { while (leftPtr<right&&theArray[leftPtr]<pivot) leftPtr++; while (rightPtr>left&&theArray[rightPtr]>pivot) rightPtr--; if (leftPtr>=rightPtr) { break; }else { swap(leftPtr, rightPtr); } } return leftPtr; } 
    10 条回复    2019-08-10 01:01:58 +08:00
    monstervivi
        1
    monstervivi  
       2019 年 8 月 8 日
    感觉你这算法写的不好,建议网上找一下别的快速排序算法

    自推一下我总结写的
    https://github.com/monsterhxw/Sorting-Algorithm-Practice/lob/master/QuickSort/main.c
    smdbh
        2
    smdbh  
       2019 年 8 月 8 日
    你说的对,是错的
    carlclone
        3
    carlclone  
       2019 年 8 月 8 日
    奇怪的写法 , pivot 一般是数组某个元素的下标吧
    nnegier
        4
    nnegier  
    OP
       2019 年 8 月 9 日 via Android
    @carlclone 这个不影响
    versionlin
        5
    versionlin  
       2019 年 8 月 9 日
    循环完成后要交换 pivot 和指针所指位置的元素,所以 pivot 一般是数组某个元素的下标。
    nomoon
        6
    nomoon  
       2019 年 8 月 9 日
    你在 swap 后面加上 leftPtr--; rightPtr++;就好了
    nnegier
        7
    nnegier  
    OP
       2019 年 8 月 9 日 via Android
    @nomoon 我怎么没想到呢,这个可以。
    nnegier
        8
    nnegier  
    OP
       2019 年 8 月 9 日 via Android
    @nomoon No,这样增加了比较次数,我刚刚解决了,有更好更简单的方式(不过还是谢谢)
    nnegier
        9
    nnegier  
    OP
       2019 年 8 月 9 日
    @nomoon 话收回收回,没有增加比较次数。我的算是您想法的改进版本。谢谢谢谢
    nomoon
        10
    nomoon  
       2019 年 8 月 10 日
    @nnegier 哈哈。。解决就好。。。不谢~~~
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3693 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 54ms UTC 04:43 PVG 12:43 LAX 21:43 JFK 00:43
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86