【重新上本科】快速排序【下】
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
}
快速排序,经典算法。当初上课的时候,应付考试,背下来就行了,就足够应付大部分考试。而后,面试的时候,基本上也是被下来就行,因为基本原理大家都清楚。但是,真正是否清楚了?我觉得,还是要把背下来的东西统统忘掉之后,再自己写一遍这个算法,才是真的清楚了其中的思想、细节。这样,心里才真正踏实,否则总有一种飘到空中的感觉,两脚不落地。
《算法导论》是从左到右遍历,设定两个指示器(从这个角度来说本质上与严蔚敏的方法一致),一个指示器指示当前遍历的位置,另一个指示的位置,该位置之前的元素(直到数组起始位置)的值都小于锚值,该位置及之右的元素的数值都大于锚值。随着第一个指示器的遍历,遇到比锚值小的元素,就与第二个指示器指示的位置的元素交换,两个指示器分别向右移动一个位置,直到第一个指示器遍历完整个数组。这部分代码如下:
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
}
快速排序,经典算法。当初上课的时候,应付考试,背下来就行了,就足够应付大部分考试。而后,面试的时候,基本上也是被下来就行,因为基本原理大家都清楚。但是,真正是否清楚了?我觉得,还是要把背下来的东西统统忘掉之后,再自己写一遍这个算法,才是真的清楚了其中的思想、细节。这样,心里才真正踏实,否则总有一种飘到空中的感觉,两脚不落地。
相关文章推荐
- 【重新上本科】快速排序【中】
- 【重新上本科】排序【调试环境】
- 快速排序
- 数据结构与算法分析 - 快速排序
- 快速排序的两种实现方法
- 快速排序
- 跟着《算法导论》学习——快速排序
- 排序算法之PHP版快速排序、冒泡排序
- 数据结构基础(4) --快速排序
- 快速排序
- 行列互转,重新命名排序
- 快速排序、归并排序的递归、非递归实现
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- C语言快速排序的例子
- 快速排序
- 快速排序 分类: 算法 2014-10-10 11:05 541人阅读 评论(0) 收藏
- 第七章 快速排序
- 关于选择排序和快速排序--2017-09-24
- c--经典算法之排序---快速排序
- 【算法】快速排序--C++源代码(VS2015)