归并排序算法
归并排序算法
咕咕咕了这么久,终于想起来要更新了
归并算法是算法思想中分治法的典型体现。分治法,顾名思义,先分后治。拿数组排序做例子,先把数组分成一个个小数组,这就是“分”,然后再将一个个小数组两两比较大小,排出一个顺序,这就是“治”。下面附上我用c#写的代码:
public class Program
{
public static void Main()
{
int[] nums = { 78, 12, 28, 98, 35, 90, 76, 36, 74, 20 };
Algorithms fun = new Algorithms();
fun.MergeSort(nums, 0, 9);
foreach(int i in nums)
{
Console.WriteLine(i);
}
}
}
public class Algorithms
{
public void Merge(int[] array, int initial, int mid, int final)
{
int n1 = mid - initial +1;
int n2 = final - mid;
int i, j, k;
int[] left = new int[n1 + 1]; //多开一位做保险,防止index超出范围
int[] right = new int[n2 + 1]; //多开一位做保险,防止index超出范围
for (i = 0; i < n1; i++)
{
left[i] = array[initial + i]; //录入数组
}
for (i = 0; i < n2; i++)
{
right[i] = array[mid + i + 1]; //录入数组
}
i = 0;
j = 0;
left[n1] = 10000; //做保险,防止index超出范围
right[n2] = 10000; //做保险,防止index超出范围
for (k = initial; k <= final; k++) //通过循环把数组排序,并合在一起
{
if (left[i] <= right[j])
{
array[k] = left[i];
i++;
}
else
{
array[k] = right[j];
j++;
}
}
}
public void MergeSort(int[] array, int initial, int final)
{
if (initial < final)
{
int mid = (initial + final) / 2;
MergeSort(array, initial, mid); //分解数组
MergeSort(array, mid + 1, final); //分解数组
Merge(array, initial, mid, final); //排序,并把数组合起来
}
else
return;
}
}
看起来很复杂,但是我们可以慢慢理解一下。首先,声明一个乱序的数组,里面有10个数。然后看 Algorithms 里面的方法。第一个方法Merge
暂时先不看,先看下面的MergeSort
,这个方法是用来分解数组的,通过递归,将数组分解为一个个只有一个数的小数组,然后进入Merge
中进行下一步操作。
在Merge
里面,我们首先声明 left 和 right 数组,放入分解的小数组,同时多开一个位置,防止后面循环中索引值超出范围,接着再把最后的数放入一个非常大的数,当两个数组同时出现最大的数,第40行的 for 循环停止,回到MergeSort
中进行下一步排序。
在经过递归之后,所有的数字都将得到排序,根据书上所说,时间复杂度为 nlgn (我还不会算orz)
这篇算法咕咕咕这么久,主要是我写了很久,报了很多错,然后自己的c#水平也很一般,导致拖了这么久,争取下次早点更新= = (不敢立flag了)
最后放张书上的图,比较生动反映这个算法。