合并(归并)排序(MergeSort)

//用来计数,测试执行循环次数.
int count;
private void button1_Click(object sender, EventArgs e)
{

Random theR = new Random(new Random().Next(30000));
List<int> theA = new List<int>();
int n = 1024;
for (int i = 1; i <= n; i++)
{
theA.Add(theR.Next(10000));
}
count = 0;
int[] theB = theA.ToArray();
MergeSort(theB, 0, n-1);
}

private void MergeSort(int[] A,int iS,int iE)
{

//相等,表示一个数,一个数认为是已排序。
if (iS == iE)
{
count++;
return;
}

//分左右两段排序,2分法
int iE1 = (iS + iE) / 2;
int iS2 = iE1 + 1;
MergeSort(A, iS, iE1);
MergeSort(A, iS2, iE);

//排完左右后进行归并针对两个排好序的段(iS-iE1,iS2-iE)进行整理
int i1 = iS, j1 = iS2;//归并初始都指向各自段得最小索引.
//因为都存放在数组的iS->iE段中,而且从小到大,从左到右存放。
//最大整理次数为iE-iS,但一般只要整理完其中一段后即可.
while(true)
{
//左边段当前值小于等于右边段最小值,则不需要移动,左边段指针i1右移一位即可。
if (A[i1] <= A[j1])
{
count++;
i1++;//右移
//因为两个段都是排序的,左边段如果整理完毕,则左边段不再需要整理
if (i1 >= j1)
{
break;
}
}
else
{
//如果左边段大于右边段,则需要移位处理.
//将j1移到i1处,原来的i1到j1-1整体右移一位.
int tmp = A[i1];
A[i1] = A[j1];
for (int b2 = j1; b2 > i1+1; b2--)
{
A[b2] = A[b2 - 1];
count++;
}
A[i1 + 1] = tmp;
i1++; j1++;
}
//因为两个段都是排序的,右边段如果整理完毕,则左边段不再需要整理
if (j1 > iE)
{
break;
}
}
}

你可能感兴趣的:(mergesort)