以前大三的时候,开了一门算法分析课,没好好听,一听到诸如背包问题,NP问题,就犯怵,但随着年龄的增长,猛然回过头,真正要学习的就是当初这些怕的东西,从归并排序开始,开始漫长的断骨重新学习算法之路。
归并排序利用了分治法的思想,首先谈谈分治法:(这里引用百度百科的定义)
分治法
可以通俗的解释为:把一片领土分解,分解为若干块小部分,然后一块块地占领征服,被分解的可以是不同的政治派别或是其他什么,然后让他们彼此异化。
分治法的精髓:
分--将问题分解为规模更小的子问题;
治--将这些规模更小的子问题逐个击破;
合--将已解决的子问题合并,最终得出“母”问题的解;
而归并排序正好可以作为分治法一个完美的例子
:
归并操作的工作原理如下:
第一步:申请空间,使其大小为两个已经
排序序列之和,该空间用来存放合并后的序列
第三步:比较两个
指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
不多说,传代码,自己凭记忆加理解相当于复制了一遍别人的成果,起到一个锻炼的效果吧
环境用的是DEV C++5.3.0.4
#include<iostream>
using namespace std;
void Merge(int a[],int first,int mid,int last,int temp[])/*合并有序序列*/
{
int i=first,j=mid+1;
int m=mid,n=last;
int k=0;
while(i<=m&&j<=n)
{
if(a[i]<=a[j])
temp[k++]=a[i++];
else
temp[k++]=a[j++];
}
while(i<=m)
temp[k++]=a[i++];
while(j<=n)
temp[k++]=a[j++];
for(i=0;i<k;i++)
a[first+i]=temp[i];
}
void MergeSort(int a[],int first,int end,int temp[])
{
if(first<end)
{
int mid=(first+end)/2;
MergeSort(a,first,mid,temp);
MergeSort(a,mid+1,end,temp);
Merge(a,first,mid,end,temp);
}
}
int main()
{
int a[5]={4,7,2,1,8};
int temp[5]={0};
for(int i=0;i<5;i++)
cout<<a[i]<<" ";
cout<<endl;
MergeSort(a,0,4,temp);
for(int i=0;i<5;i++)
cout<<a[i]<<" ";
cout<<endl;
}
归并排序实现起立其实不是想象中那么困难,而本人在大三的时候,可能就是因为心里发怵,所以很多本该在几年前就该掌握的东西,到今天才敢重新拾起,尽管我还是不明朗自己未来的方向,但从这一个归并排序开始,我开始重新夯实自己的基本功,一步一个脚印。