一、针对经典归并排序算法问题的改进措施
(1)针对递归层次问题
采用能在小规模集合上有效工作的其它算法,直接对小规模集合处理。
如INSERTIONSORT算法
(2)针对元素频繁移动问题
采用一个称为链接信息数组LINK(1:n)的数据结构,记录归并过程中A中的元素相对于其排序后在分类表中位置坐标的链接关系。
LINK(i)取值于[1,n],是指向A的元素的指针:在分类表中它指向下一个元素在A中的位置坐标。
二、具体实现
m_improved.h
#pragma once
//直接插入排序
void insertSort(int a[], int link[], int left, int right, int &p)
{
int temp;
int i, j;
int start = left, end = left;
for (i = left + 1; i <= right; i++)
{
if (a[i] <= a[start])
{
link[i] = start;
start = i;
}
else if (a[i] > a[end])
{
link[end] = i;
end = i;
link[end] = -1; //-1代表结束
}
else
{
temp = start;
for (j = 0; j < i; j++)
{
if (a[i] > a[temp] && a[i] <= a[link[temp]])
{
link[i] = link[temp];
link[temp] = i;
break;
}
temp = link[temp];
}
}
}
p = start;
}
//改进归并排序
void mergeImproved(int a[], int link[], int q, int r, int &p)
{
int i = q, j = r, k = 0;
int start;
if (a[q] <= a[r])
{
start = q;
k = i;
i = link[i];
}
else
{
start = r;
k = j;
j = link[j];
}
while (i != -1 && j != -1)
{
if (a[i] <= a[j])
{
link[k] = i;
k = i;
i = link[i];
}
else
{
link[k] = j;
k = j;
j = link[j];
}
}
if (i == -1)
link[k] = j;
else
link[k] = i;
p = start;
}
void mSortImproved(int a[], int link[], int left, int right, int &p)
{
if (right - left + 1 < 20)
{
insertSort(a, link, left, right, p);
}
else
{
int center = (left + right) / 2;
int q, r;
mSortImproved(a, link, left, center, q);
mSortImproved(a, link, center + 1, right, r);
mergeImproved(a, link, q, r, p);
}
}
主函数中应用实例
#include"m_improved.h"
void main()
{
int a[3000];
int i = 0;
for (i = 0; i < 3000; i++)
{
a[i] = rand();
}
int pa = -1; //这里要注意一下,我一开始置为0了,就死循环了...
int la[3000];
memset(la, -1, 3000 * sizeof(int));
mSortImproved(a, la,0,2999,pa);
}
经过运行时间测试,改进算法的确比经典算法要快~
PS:这样的话是看不到排序后的结果的,如果需要,那就自己加几句代码8