一、算法步骤(大体框架)
1).设待排序的记录存储在array[1...n]中,可以把第一个记录array[1]看作一个有序序列
2).依次将array[i=2,...,n]寻找合适的插入点(枚举搞定)插入已经排好序的序列array[1...i-1]中
二、举个肥肠简单的栗子
例如利用直接插入排序对序列{12,2,16,}进行排序
1).初始状态——把array[1]看作一个有序序列
| 0 | 1 | 2 | 3 |
| 12 | 2 | 16 | |
| 已经有序序列 |
2).将array[2]插入有序序列array[1],插入前先和前一个记录比较
- array[2]<array[1]——将array[2]暂存到array[0]中,array[1]后移一位
如表格:
| 0 | 1 | 2 | 3 |
| 2 | 12 | 16 | |
| 暂存到array[0] | 没有东西 | 后移一位 |
- 然后将array[0]中的记录放入array[1]——得到有序序列array[1...2]
如表格:
| 0 | 1 | 2 | 3 |
| 2 | 12 | 16 | |
| 已经有序 | 已经有序 |
|
3).将array[3]插入有序序列array[1..2],插入前先和前一个比较
- array[3]>array[2]——什么都不做——得到有序序列array[1..3]
如表格:
| 0 | 1 | 2 | 3 |
| 2 | 12 | 16 | |
| 已经有序 | 已经有序 | 已经有序 |
三、最重要的Code!!
下面是直接插入排序的模板!
void StraightInsertSort(int Array[],int n)//直接插入排序
{
for(int i = 2;i <= n; ++i)
{
if(Array[i] < Array[i - 1])//Array[i]与前一个元素array[i-1]比较
{
Array[0] = Array[i];//暂存Array[0]
Array[i] = Array[i - 1];//Array[i-1]后移一位
int j;
for(j = i - 2;Array[j] > Array[0]; --j)//从后向前寻找插入位置,逐个后移,直到找到插入位置
Array[j + 1] = Array[j];//Array[j]后移一位
Array[j + 1] = Array[0]; //Array[0]插入array[j+1]位置
}
}
}
四、算法复杂度
1.时间复杂度
根据待排序序列的不同,找插入位置的复杂度是不同的,可分为最好情况、最坏情况和平均情况
最好情况——本身正序:n-1次比较=O(n)
最坏情况——本身逆序:=
平均情况:等于最好情况和最坏情况的平均数,也为
2.空间复杂度
使用了辅助空间array[0],空间复杂度为
3.稳定性
这个可以读者自己创编数据进行证明,这里给出答案:稳定
五.拓展——折半插入排序
折半插入排序每次将待排序记录插入一个有序序列(和直接插入排序一样),
但在查找待排序记录的插入位置时,采用二分法效率更高!
时间复杂度:O(n^2)
稳定性:稳定。
空间复杂度:O(1)
给出实现代码:
void Binary_Array_Sort()
{
int j,x,mid,l,r;
for(int i = 1; i < n; i++)
{
x = Array[i];
l = 0;
r = i - 1;
while(l <= r)//二分插入位置
{
mid = (l + r) / 2;
if (x >= Array[mid]) l = mid + 1;
else r = mid - 1;
}
for(j = i - 1;j > r; --j) Array[j + 1] = Array[j];
Array[j + 1] = x;
}
}
六、推荐书籍
《趣学数据结构》 陈小玉 著 人民邮电出版社
本文详细介绍了直接插入排序的算法步骤,通过一个简单例子解释了排序过程,并给出了排序代码模板。同时,讨论了算法的时间复杂度和空间复杂度,指出其稳定性。此外,还提及了折半插入排序作为拓展,它利用二分法提高查找插入位置的效率,同样具有稳定性。
1880

被折叠的 条评论
为什么被折叠?



