数据结构与算法学习记录:快速排序 (转)
2011-05-11 11:55
281 查看
数据结构与算法学习记录:快速排序
快速排序的基本思想:
分治法,即,分解,求解,组合 .
[b]分解:
在无序区R[low..high]中任选一个记录作为基准(通常选第一个记录,并记为Pivot,其下标为pivotpos),以此为基准划分成两个较小的子区间R[low,pivotpos - 1]和R[pivotpos + 1 , high],并使左边子区间的所有记录均小于等于基准记录,右边子区间的所有记录均大于等于基准记录,基准记录无需参加后续的排序。而划分的关键是要求出基准记录所在的位置pivotpos.
求解:
通过递归调用快速排序对左、右子区间R[low..pivotpos-1]和R[pivotpos+1..high]快速排序
组合:
当"求解"步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,"组合"步骤无须做什么,可看作是空操作。
具体过程:
设序列为R[low,high],从其中选第一个为基准,设为pivot,然后设两个指针i和j,分别指向序列R[low,high]的起始和结束位置上:
1),将i逐渐增大,直到找到大于pivot的关键字为止;
2),将j逐渐减少,直到找到小于等于pivot的关键字为止;
3),如果i<j,即R[i,j]的元素数大于1,则交换R[i]和R[j];
4),将基准记录pivot放到合适的位置上,即i和j同时指向的位置,则此位置为新的pivotpos。
备注:
快速排序是不稳定排序,即相同的关键字排序后,相对位置是不确定的。
示例代码:
public class DataStructure_QuickSort
{
//划分子区间,计算基准位置
int Partition(int[] arr , int nLower ,int nUpper)
{
int pivot = arr[nLower] ;//取第一个记录为基准记录
int nLeft = nLower + 1; //加1,pivot无需和自身做比较
int nRight = nUpper ;
int temp ;
do{
while (nLeft <= nRight && arr[nLeft] <= pivot) //将nLeft逐渐增大,直到找到大于pivot的下标为止
nLeft++ ;
while (nLeft <= nRight && arr[nRight] > pivot) //从nRight逐渐减少,直到找到小于等于pivot的下标为止
nRight-- ;
//R[nLeft,nRight]区间的长度(元素数)大于1时,交换R[nLeft]和R[nRight]
if (nLeft < nRight)
{
temp = arr[nLeft] ;
arr[nLeft] = arr[nRight] ;
arr[nRight] = temp ;
nLeft++;
nRight--;
}
} while (nLeft < nRight); //当nLeft == nRight的时候停止循环
//把基准记录pivot放到正确位置,即nLeft和nRight同时指向的位置
temp = arr[nLower];
arr[nLower] = arr[nRight];
arr[nRight] = temp ;
return nRight ;
}
public void QuickSort(int[] arr, int nLower, int nUpper)
{
int pivotpos; //基准下标
if (nLower < nUpper) //仅当区间范围长度大于1时才须排序
{
pivotpos = Partition(arr, nLower, nUpper);//划分子区间,知道基准下标(QuickSort的关键)
QuickSort(arr, nLower, pivotpos - 1); //对左区间递归排序
QuickSort(arr, pivotpos + 1, nUpper); //对右区间递归排序
}
}
}
[/b]
快速排序的基本思想:
分治法,即,分解,求解,组合 .
[b]分解:
在无序区R[low..high]中任选一个记录作为基准(通常选第一个记录,并记为Pivot,其下标为pivotpos),以此为基准划分成两个较小的子区间R[low,pivotpos - 1]和R[pivotpos + 1 , high],并使左边子区间的所有记录均小于等于基准记录,右边子区间的所有记录均大于等于基准记录,基准记录无需参加后续的排序。而划分的关键是要求出基准记录所在的位置pivotpos.
求解:
通过递归调用快速排序对左、右子区间R[low..pivotpos-1]和R[pivotpos+1..high]快速排序
组合:
当"求解"步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,"组合"步骤无须做什么,可看作是空操作。
具体过程:
设序列为R[low,high],从其中选第一个为基准,设为pivot,然后设两个指针i和j,分别指向序列R[low,high]的起始和结束位置上:
1),将i逐渐增大,直到找到大于pivot的关键字为止;
2),将j逐渐减少,直到找到小于等于pivot的关键字为止;
3),如果i<j,即R[i,j]的元素数大于1,则交换R[i]和R[j];
4),将基准记录pivot放到合适的位置上,即i和j同时指向的位置,则此位置为新的pivotpos。
备注:
快速排序是不稳定排序,即相同的关键字排序后,相对位置是不确定的。
示例代码:
public class DataStructure_QuickSort
{
//划分子区间,计算基准位置
int Partition(int[] arr , int nLower ,int nUpper)
{
int pivot = arr[nLower] ;//取第一个记录为基准记录
int nLeft = nLower + 1; //加1,pivot无需和自身做比较
int nRight = nUpper ;
int temp ;
do{
while (nLeft <= nRight && arr[nLeft] <= pivot) //将nLeft逐渐增大,直到找到大于pivot的下标为止
nLeft++ ;
while (nLeft <= nRight && arr[nRight] > pivot) //从nRight逐渐减少,直到找到小于等于pivot的下标为止
nRight-- ;
//R[nLeft,nRight]区间的长度(元素数)大于1时,交换R[nLeft]和R[nRight]
if (nLeft < nRight)
{
temp = arr[nLeft] ;
arr[nLeft] = arr[nRight] ;
arr[nRight] = temp ;
nLeft++;
nRight--;
}
} while (nLeft < nRight); //当nLeft == nRight的时候停止循环
//把基准记录pivot放到正确位置,即nLeft和nRight同时指向的位置
temp = arr[nLower];
arr[nLower] = arr[nRight];
arr[nRight] = temp ;
return nRight ;
}
public void QuickSort(int[] arr, int nLower, int nUpper)
{
int pivotpos; //基准下标
if (nLower < nUpper) //仅当区间范围长度大于1时才须排序
{
pivotpos = Partition(arr, nLower, nUpper);//划分子区间,知道基准下标(QuickSort的关键)
QuickSort(arr, nLower, pivotpos - 1); //对左区间递归排序
QuickSort(arr, pivotpos + 1, nUpper); //对右区间递归排序
}
}
}
[/b]
相关文章推荐
- 数据结构与算法学习记录:快速排序
- 算法学习记录1 快速排序
- 【学习记录】4.使用Arrays给数组排序
- 【记录】JavaScript版 快速排序,还请高手指教。
- 数据结构与算法学习-快速幂取模
- 算法学习之排序(5)--快速排序
- 快速排序学习笔记
- 算法学习记录-排序——堆排序
- [MySQL]学习笔记- 用户行为表中,查询每个人的一条最新行为(分组 排序 取时间最大的一条记录)
- c++学习之--排序3-快速排序
- 关于Linux的快速启动(fastboot)和低功耗(low power)的学习记录
- java学习记录——使用Arrays.sort对数组进行升序排序
- 算法学习~分治法~快速排序
- 基础算法学习笔记—快速排序
- 黑马程序员之数据结构学习笔记:快速排序
- 快速排序-理论学习用
- 学习笔记之快速排序
- 快速排序 (QuickSort) Java数据结构与算法
- 学习Discuz! X3.2记录:快速回复插件,通过js使选择的下拉列表填充到回帖内容中
- 啊哈!算法 学习2 排序 - 快速排序 2分发排序