我正在写一个快速排序程序。为此我需要对数组进行分区。分区由函数paritionIt()
完成。我编写了一个分区数组的代码,如下所示:
int partition(int beg,int end,double key)
{
int pLeft = beg;
int pRight = end-1;
while(pLeft<pRight)
{
while(array[++pLeft]<key);
while(array[--pRight]>key);
if(pLeft<pRight)
swap(pLeft,pRight);
}
swap(pLeft,end-1);
return pLeft;
}
这个块似乎在隔离执行时工作正常。但是,当与其他功能一起运行时,似乎会产生错误的答案。给我的以下代码使所有问题都消失了,但它与我的代码没什么不同。
int partitionIt(int left, int right, double pivot)
{
int leftMark = left; //right of first elem
int rightMark = right - 1; //left of pivot
while(true)
{
while( theVect[++leftMark] < pivot ) //find bigger
; // (nop)
while( theVect[--rightMark] > pivot ) //find smaller
; // (nop)
if(leftMark >= rightMark) //if pointers cross,
break; // partition done
else //not crossed, so
swap(leftMark, rightMark); //swap elements
} //end while(true)
swap(leftMark, right-1); //restore pivot
return leftMark; //return pivot location
} //end partitionIt()
该区块似乎与我的相似,但正在给出正确答案,而我的不是。你可以告诉我partition()
和partitionIt()
之间的区别。
答案 0 :(得分:1)
区别在于你打破了循环结构。
在你的代码中,你进行了两次条件检查,而在给定的代码中,你只做了一次。
假设您已经循环了一段时间。 (没有双关语)。
你会点击这段代码:
if(pLeft<pRight)
swap(pLeft,pRight);
然后你会点击while循环的底部,回到顶部,然后再次检查是否pLeft<pRight
。如果不是这样,我们退出循环。
在给定的代码中,执行交换,但随后执行以下操作:
while( theVect[++leftMark] < pivot ) //find bigger
; // (nop)
while( theVect[--rightMark] > pivot ) //find smaller
; // (nop)
你然后检查你是否突破了循环。
这似乎是差异所在。
编辑:澄清 - 首次进入循环时while(pLeft>=pRight)
会发生什么?
在给定的代码中,您将继续while
循环,直到它中断,但在您的代码中,您永远不会进入循环体。
答案 1 :(得分:1)
我唯一能看到的就是功能会
如果使用left + 1 == right
调用,则表现不同:您的
函数不会进入循环,但会返回beg
;该
书中的函数将进入循环,从而递增
在进行决赛之前leftMark
并递减rightMark
交换并返回leftMark
。