大开始这个算法之前,我一定要大大的夸赞我的团队,让我从茫然到茅塞顿开,真的是很棒的体验。算法真的很有趣,希望经过一段时间的解除,能让算法认识我,哈哈!
今天给大家讲讲分治算法,其实分支里面还有递归的概念,但是时间有限,今天就不讲了,下次讲吧。
有位大神告诉我,要想把事情做的有效率,有质量,就要有分治和抽象的思想,那么到底什么是分治呢?字面意思:分开治理,此处举一个归并排序的例子吧。
归并排序 是成功应用分治法的完美例子,基本思想是静待排序元素分成大小大致相同的另个子序列,分别对着两个子序列进行排序,最终将排好序的子序进行排序,最终将排好序的子序列合并为所要求的序列
分为三个步骤:
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++} } } } }