1. 算法思想
分而治之的思想类似于软件的模块化设计方法,它将一个大问题分解成多个小问题,然后由小问题的解获得大问题的解。
通常,由分而治之算法所得到的小问题与原来的大问题具有相同的类型,因此当分解后的小问题相对而言还是较大是,可根据需要对小问题继续采取分而治之的方法来求解,由此可见,分而治之算法可通过递归方式来实现。
2. 应用
2.1 归并排序
对n个元素进行排序:若n=1则排序终止,否则将这个序列分为两个子序列,再对每一个子序列进行排序,然后将两个子序列合并为一个,最终所有的子序列都归并为一个有序序列
void MergeTwo(int s[], int L, int midR, int R,int n[]) //合并两部分
{
for (int i = L, j = midR + 1,l=L; l<=R;l++)
{
if (i<=midR&&s[i] < s[j])
{
n[l] = s[i];
i++;
}
else {
n[l] = s[j];
j++;
}
}
for (int i = L; i <= R; i++)
s[i] = n[i];
}
void MSort(int s[],int L,int R,int n[])
{
if (L < R)
{
MSort(s, L, (L + R) / 2,n); //对左半部分排序
MSort(s, (L + R) / 2+1,R ,n); //对右半部分排序
MergeTwo(s, L, (L + R) / 2, R,n); //合并两部分
}
}
void MergeSort(int s[],int len)
{
if (len > 1)
{
int* n = new int[len] {};
MSort(s, 0, len - 1,n);
delete[] n;
}
}
2.2 快速排序
每次都从待排序的序列中选择一个值(轴值),然后以该值为基准,将原来的序列分割为左、右两个部分,其中左边的部分的元素均小于轴值,右边的部分的元素均大于或等于轴值,这个轴值的位置也就是最终序列的轴值的位置,再对左右序列分别进行分割,直至序列长度为1,这样所有元素都在其应该在的位置。
int qSort(int s[], int L, int R)
{
int piv = L;
int p = s[piv];
for (int i = L + 1; i <= R; i++)
{
if (s[i] < s[piv])
{
piv++;
if (i != piv)
swap(s[i], s[piv]);
}
}
s[L] = s[piv];
s[piv] = p;
return piv;
}
void QSort(int s[], int L,int R)
{
if (L < R)
{
int piv = qSort(s, L, R);
QSort(s, L, piv - 1);
QSort(s, piv + 1, R);
}
}
void QuickSort(int s[], int len)
{
QSort(s, 0, len - 1);
}