大开始这个算法之前,我一定要大大的夸赞我的团队,让我从茫然到茅塞顿开,真的是很棒的体验。算法真的很有趣,希望经过一段时间的解除,能让算法认识我,哈哈!
今天给大家讲讲分治算法,其实分支里面还有递归的概念,但是时间有限,今天就不讲了,下次讲吧。
有位大神告诉我,要想把事情做的有效率,有质量,就要有分治和抽象的思想,那么到底什么是分治呢?字面意思:分开治理,此处举一个归并排序的例子吧。
归并排序 是成功应用分治法的完美例子,基本思想是静待排序元素分成大小大致相同的另个子序列,分别对着两个子序列进行排序,最终将排好序的子序进行排序,最终将排好序的子序列合并为所要求的序列
分为三个步骤:
1、分解:经n个元素分成各含n/2个元素的子序列
2、求解:用归并排序对两个子序列递归的排序
3、合并:合并两个已经排好的子序列排序得到排序结果
在讨论的时候,最让人兴奋的是发现问题,然后和大家激烈讨论出结果,这种及时的反馈比中奖还高兴。
请大家思考一下几点:
1、为什么用L[50],R[50]数组
2、n1,n2有什么作用
3、L[n1]=INT_MAX;
R[n2]-INT_MAX;有什么作用
4、i,j 为什么从0开始,从1开始不行吗?
5、合并的时候,两个已排好序的序列式怎样排序的,这块代码特别有意思,一定要亲手实践
for(k=p,k<r+1,k++)//核心代码:合并
{
if (L[i]<R[j])
{
A[k]=L[i];
i++;
}
else
{A[k]=R[j];j++}
}
demo
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 分治法
{
class Program
{
static void Main(string[] args)
{
}
//归并排序 是成功应用分治法的完美例子,基本思想是静待排序元素分成大小大致相同的另个子序列,分别对着两个子序列进行排序,最终将排好序的子序进行排序,最终将排好序的子序列合并为所要求的序列
void MergeSort(int A[],int p,int r)
{
int q;
if (p<r)
{
//1、分解:经n个元素分成各含n/2个元素的子序列
q=(p+r)/2;
//2、求解:用归并排序对两个子序列递归的排序
MergeSort (A,p,q);
MergeSort (A,q+1,r);
Merge(A,p,q,r);
}
}
//函数Merge(A,p,q,r)的C 代码如下:
void Merge(int A[],int p,int q,int r)
{
int n1=q-p+1,n2=r-q,i,j,k;
int L[50],R[50];
for(i=0,i<n1,i++)
{
L[i]=A[p+i];
}
for(j=0,j<n2,j++)
{
R[i]=A[q+j+1];//?注意加1
}
L[n1]=INT_MAX;
R[n2]-INT_MAX;
i=0;
j=0;
//3、合并:合并两个已经排好的子序恶劣已得到排序结果
for(k=p,k<r+1,k++)//核心代码:合并
{
if (L[i]<R[j])
{
A[k]=L[i];
i++;
}
else
{A[k]=R[j];j++}
}
}
}
}