一、插入排序
1.思路:插入排序由N-1趟排序组成,对于P=1趟到P=N-1趟,插入排序保证位置0到位置P为已排序状态,位置0到位置P-1是已排过序的。
2.实现:在第P趟,将位置P上的元素移动到前P+1个元素正确的位置上。
3.分析:算法复杂度为O(N2),如果为顺序的话复杂度为O(N)。
4.定理:通过交换相邻元素进行排序的任何算法平均需要Ω(N2)时间(下界)。
我最初的思路,复杂度为O(N2),即使是在都是顺序的情况下。
void MyInsertionSort(ElementType A[], int N)
{
int j, P;
ElementType tmp, exc;
for (P = 1; P < N; P++)
{
tmp = A[P];
for (j = P; j > 0; j--)
{
if (A[j-1] > tmp)
{
exc = A[j-1];
A[j-1] = A[j];
A[j] = exc;
}
tmp = A[j - 1];
}
}
}
书上的算法,该算法在顺序的情况下比我的快,因为内层for循环检测总是立即判定不成立而终止。
void InsertionSort(ElementType A[], int N)
{
int j, P;
ElementType tmp;
for (P = 1; P < N; P++)
{
tmp = A[P];
for (j = P; j > 0 && A[j - 1] > tmp; j--)//若条件已满足,此时j的值已减一
A[j] = A[j - 1];
A[j] = tmp;
}
}
二.希尔排序
前言:通过上面得插入排序结论,我们可以得知,要想使一个排序算法以亚二次运行或O(N2)运行,必须进行一些比较,特别是相邻较远的元素比较。
1.定义:希尔排序通过比较相距一定间隔的元素来工作,直到比较相邻元素的最后一趟排序为止,又名缩小增量排序。
2.思路:希尔排序使用一个增量序列h1,h2,h3,...,ht,只要h1等于1,任何序列都是可行的,在使用增量hk的一趟排序后,对于每一个i有
A[i]<=A[i+1],相隔hk的元素都是排序的。
3.实现:ht=N/2(向上取整)
4.分析:算法的复杂度在O(N)和O(N2)之间,与选择的增量序列有关。
以下是算法的实现,我们根据直接插入排序的思想,照猫画虎,可以写出希尔排序:
void ShellSort(ElementType A[], int N)
{
int i, j, increment;
ElementType tmp;
for(increment = N/2; increment > 0; increment /= 2)//外循环次数为缩小增量的个数
for (i = increment; i < N; i++)
{ //从增量位置i开始逐渐增加移动位置,
//由后向前,以增量间隔缩小倍数的位置为要排序的数据,
//按照直接插入排序的思想进行排序。
tmp = A[i];
for (j = i; j >= increment; j -= increment)
if (A[j - increment] > tmp)
A[j] = A[j - increment];
else
break;
A[j] = tmp;//此处的j已经是原来的i的位置
}
}
编程简单特点使得它成为对适度的大量输入数据经常选用的算法。