归并算法其实理解起来很容易,我们以前在学习C++的时候,肯定遇到过这样一道题目,给两个有序的列表,请把他们合并成一个列表,并且有序。相信叫大家写一个函数实现这个功能并不难。但是我们当时怎么没有想到,用这个思想,可以发明出一种排序的算法出来呢,它就是我们要学习的归并排序。
归并排序的原理就是,把一个序列拆分成两个小的序列,把这两个 小的序列排好序好,然后再把它们合并起来。对于每个小的序列,我们又可以进行拆分成更小的两个序列,把更小的两个序列排序好后,合并起来。对于更小的序列,我们又可以进行拆分,一直这样拆分,直到拆分到每个序列里面只有一个数的时候,这个时候,就把这个数当作一个列表,跟另外一个列表实现合并,并有序。
比如我们要排序的序列有10个数,我们可以把这10个数当成10个序列,对每两个序列进行排序并合并成一个序列,这时候,就有了5个序列,然后再把这一个序列里面的两两排序合并,一直到最后合并成了一个序列,那么这个序列也就变成了有序的了。
上面的就是归并排序的基本原理示意图.最重要的一步就是给你两个有序的列表,把它合并成一个有序的列表,这个方法实现如下:
/// <summary>
/// 把两个有序的序列A和B合并到一个有序列temp里面
/// </summary>
/// <param name="sortListA">有序序列A</param>
/// <param name="sortListB">有序序列B</param>
/// <param name="tempList">有序序列Temp</param>
public void Merge(List<int> sortListA, List<int> sortListB, List<int> tempList)
{
int countB = 0;
int countA = 0;
//1.以某个序列为原始序列,把它的每一个数,与另外的一个序列做比较
for (int i = 0; i < sortListA.Count; i++)
{
//1.1循环遍历序列B的每一个序列(因为B序列是有序列的,所以第一个元素是最小的)
for (int j = countB; j < sortListB.Count; j++)
{
//1.2如果A序列中的某个元素比B中的小,就把A中的这个元素加到temp中去
if (sortListA[i] < sortListB[j])
{
tempList.Add(sortListA[i]);
countA++;//记录加到temp中去的A序列中元素的数量
break;
}
//1.2否则把B中的元素加到temp中去
else
{
tempList.Add(sortListB[j]);
countB++;//记录加到temp中去的B序列中元素的数量
}
}
}//注意,此for循环结束后,一定有一个序列中的元素全部加到了temp中去了。
//如果此处不相等,代表B中的元素还没有加完,那么把B中剩下的元素加入到Temp中去
if (countB != sortListB.Count)
{
for (int k = countB; k < sortListB.Count; k++)
{
tempList.Add(sortListB[k]);
}
}
//否则的话,代表A中的元素还没有加完,那么把A中剩下的元素加入到Temp中去
else
{
for (int k = countA; k < sortListA.Count; k++)
{
tempList.Add(sortListA[k]);
}
}
}
递归调用的方法如下:
public void MSort(List<int > sortList, List<int > resultList,int start,int end)
{
List<int> tempList1 = new List<int>();
List<int> tempList2 = new List<int>();
int mid = (start + end) / 2;
if (start == end)
{
resultList.Add(sortList[start]);
}
else
{
MSort(sortList, tempList1, start, mid);//递归调用,把SortList里面,第start到mid之间的数,进行归并,结果放在tempList1里面
MSort(sortList, tempList2, mid+1, end);//递归调用,把SortList里面,第mid+1到end之间的数,进行归并,结果放在tempList2里面
//resultList = Merge(tempList1, tempList2);//不能这样调用,
Merge(tempList1, tempList2, resultList);//把TempList1和TempList2中的数合并到resultList中去
}
}
最后实现的排序方法是:
public List<int> SortByMerge(List<int> sortList)
{
List<int> resultList=new List<int>();
MSort(sortList, resultList, 0, sortList.Count - 1);
return resultList;
}