您的位置:首页 > 其它

【重新上本科】快速排序【下】

2012-08-20 22:54 120 查看
在我的印象中,绝大多数的教科书讲解快速排序的时候,都用严蔚敏书中的方法,采用左右两个迭代指示器,从两个方向进行遍历比较。能不能只从一个方向进行遍历,遍历一遍就能完成交换任务呢?《算法导论》提供了一种方法。

《算法导论》是从左到右遍历,设定两个指示器(从这个角度来说本质上与严蔚敏的方法一致),一个指示器指示当前遍历的位置,另一个指示的位置,该位置之前的元素(直到数组起始位置)的值都小于锚值,该位置之右的元素的数值都大于锚值。随着第一个指示器的遍历,遇到比锚值小的元素,就与第二个指示器指示的位置的元素交换,两个指示器分别向右移动一个位置,直到第一个指示器遍历完整个数组。这部分代码如下:

int i = iLow; // 遍历指示器i,i左边的元素都比锚值小,右边的元素都比锚值大

int iVal = Array[iHigh]; // 锚值设定为最后一个元素,与上面两种方法不同,这个取决于遍历数组的方向,总在该方向末尾的元素

for (int j=iLow; j<iHigh; j++) // 便利指示器j,用于遍历整个数组的元素,在遍历过程中,j >= i,等号只在开始遍历时成立

{

if (Array[j] <= iVal) // 当j位置元素小于锚值时,两者交换(此时位置i的元素一定大于锚值),两个指示器均右移,此时区间 [i,j)的数值均大于锚值

{

int iTemp = Array[i];

Array[i] = Array[j];

Array[j] = iTemp;

i++;
}
}

int iTemp = Array[i]; // 边界情况,当跳出循环,将Array[iHigh]存放的锚值,与位置i的元素交换;两个子序列区间是[iLow, i)和(i, iHigh].

Array[i] = Array[iHigh];

Array[iHigh] = iTemp;

完整的算法代码是:

void QuickSort3 (int Array[], int iLow, int iHigh)

{

if (iLow < iHigh)

{

int i = iLow; // 遍历指示器i,i左边的元素都比锚值小,右边的元素都比锚值大

int iVal = Array[iHigh]; // 锚值设定为最后一个元素,与上面两种方法不同,这个取决于遍历数组的方向,总在该方向末尾的元素

for (int j=iLow; j<iHigh; j++) // 便利指示器j,用于遍历整个数组的元素,在遍历过程中,j >= i,等号只在开始遍历时成立

{

if (Array[j] <= iVal) // 当j位置元素小于锚值时,两者交换(此时位置i的元素一定大于锚值),两个指示器均右移,此时区间 [i,j)的数值均大于锚值

{

int iTemp = Array[i];

Array[i] = Array[j];

Array[j] = iTemp;

i++;
}
}

int iTemp = Array[i]; // 边界情况,当跳出循环,将Array[iHigh]存放的锚值,与位置i的元素交换;两个子序列区间是[iLow, i)和(i, iHigh].

Array[i] = Array[iHigh];

Array[iHigh] = iTemp;

} //if

}

快速排序,经典算法。当初上课的时候,应付考试,背下来就行了,就足够应付大部分考试。而后,面试的时候,基本上也是被下来就行,因为基本原理大家都清楚。但是,真正是否清楚了?我觉得,还是要把背下来的东西统统忘掉之后,再自己写一遍这个算法,才是真的清楚了其中的思想、细节。这样,心里才真正踏实,否则总有一种飘到空中的感觉,两脚不落地。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: