插入排序:
- 基本思想:
可以这样理解:将无序的区间插入到有序的区间里 - 分类:
1)直接插入排序
2)希尔排序
3)折半插入排序
1、直接插入排序:
- 基本思想:
将第i个记录插入到第i-1个序列中,将第i个数对应的关键字k与第i-1前面排好序的数进行比较,(我们这里以降序为例)如果k是比前面的数都小的,那么直接进行插入,否则在第i-1个数中进行寻找合适的位置,找到之后再进行插入。 - 图示:
- 代码实现:
void Sort(int* a,int n)
{
int i = 0;
for(i = 1; i<n; i++)
{
int temp = a[i];
int end = i-1;
while(end >= 0)
{
if(a[end] < temp)
{
a[end+1] = a[end];
end--;
}
else
{
break;
}
}
a[end+1] = temp;
}
}
- 时间复杂度
1)最坏的情况(逆序):O(N)
2)最好的情况(正序):O(N^2) - 空间复杂度
O(1) - 直接插入排序的稳定性:
1)是稳定的排序方法
2)它的优缺点:它的排序效率算是比较高的一种排序方法,但是当数据不断增多的时候,它的劣势也就增加了
2、折半插入排序:
基本思想:
我们知道在直接插入排序中被插入的区间是已经有序的,所以当我们在进行插入的时候,不用挨个进行比较,采用折半的方法来进行比较,这样效率就提高了代码实现:
for(int i = 1; i<n; i++)
{
int low = 0;
int key = a[i];
int high = i-1;
while(low <= high)
{
int mid = low-((high-low)>>1);
if(a[mid] > key)
high = mid-1;
else
left = mid+1;
}
int end = i-1;
while(end >= 0)
{
if(a[end] > key)
{
a[end+1] = a[end];
end--;
}
else
{
break;
}
}
a[end+1] = temp;
}
3、希尔排序:
- 基本思想:
我们知道在进行直接插入排序的时候如果遇到了逆序的情况,此时效率会很低,希尔这个人他就在想,如果是这样的情况,有没有一种方式,在进行直接插入排序的之前,将要排序的数变成接近有序。因此就出现了现在的另一种排序方法:希尔排序,其实它也是对直接插入排序的一种优化。 - 图示说明:
- 代码实现:
void Sort(int* a, int n)
{
int i = 0;
int gap = n;
int end = 0;
while(gap>1)
{
gap = gap/3+1;
for(i = gap; i<n; i++)
{
int temp = a[i];
end = i-gap;
while(end >= 0)
{
if(a[end] < temp)
{
a[end + gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end+gap] = temp;
}
}
}
- 时间复杂度和空间复杂度
1)时间复杂度
它的时间复杂度不是很容易计算的:
大体的时间复杂度就是:O(N)< O(希尔)