【1】直接插入排序
原理:联想平时打扑克牌,手上的牌都是排好序的,新起的牌只需从最后往前比较,然后插入即可。
步骤:
1.从第一个元素开始a[0],认为已排序。
2.从第二个元素a[1]开始依次,a[i]和前边的元素比较。第一个循环,正向遍历a[i]直到数组末尾
这里边又涉及一个逆向比较的循环,即j=i,j--依次和前边的数比较,直到a[j-1]<a[j]。
最好情况:O(n) 即都排好序,只需从第二个元素开始循环1,和前一个元素比较,大于前一个元素,i++
最坏情况:O(N^2) 所有元素都逆序,需要(1+2+……+n-1)次交换
平均: n^2/4 比选择排序少一半的移动
稳定排序
代码:
/*********************直接插入排序*************************/
void DirectInsertSort(int a[],int length)
{
for(int i = 1;i < length;i++)//从第2个元素开始,依次往前比较
{
for(int j = i;j>0;j--)//第i个元素依次和前i-1个比较
{
if(a[j]<a[j-1])//
swap(a[j],a[j-1]);
else
break;
}
}
for(int i =0;i<length;i++)
cout << a[i] <<" ";
}
---------------------------------------------------------------------------------------------------------------------
【2】希尔排序
原理:
根据步长选取一段段区域元素进行对应位置的比较,也曾递减增量排序,因为步长在不断地变小。最后变为步长为1的比较,即为一般插入排序,从后往前比。
步骤:
1.选取h=len/2作为初始步长,h不断折半,直到为1
2.从h处的元素不断和前边比较
2.如果后边的元素比前边一段段中对应的元素小,则把对应元素后移,最后不满足条件处赋值为比较的元素。
最好:O(n)
最坏:O(nlogn)
/****************希尔排序******************/
void ShellSort(int a[],int length)
{
int j;
for(int h = length/2;h > 0;h /= 2)//每段比较元素增量为h
{
for(int i = h;i < length;i++)//从a[h]开始,不断和前边相差h、2h……的元素比较,
{
int temp = a[i];//待比较元素
for(j = i;j >= h;j -= h)//从a[h]开始,不断和前边比较,一直到第一个h段的元素
{
if(temp < a[j-h])//如果待比较元素temp小于前边的任一一个,则把前边的元素后移
a[j] = a[j-h];
else
break;
}
a[j] = temp;//最后把跳出循环不满足条件处的元素赋值为temp,因为j在不断变换,所以设置temp,此处的元素已经移到了a[j+h]处
}
}
for(int i =0;i<length;i++)
cout << a[i] <<" ";
}