本文介绍: 注意:while循环的条件gap大于1并不是说gap不能为1,而是这里在前面的进入循环的时候就有可能为1了,记住gap是先缩小再使用的,进入循环时(还没有缩小)的gap是上次使用的gap。希尔排序与插入排序很像,单趟排序的思路基本相似,不同的是,插入排序的每次对比一个指向的元素是向前移动一个距离,希尔排序是移动gap个距离,从大到小,最后为1。再进行循环的判断,如果条件不是大于1的话,而是大于等于1,那么gap为1可以进入循环,然后1除1等于1,1+1等于2,就死循环了。
一、插入排序
思路:
插入排序就像玩扑克牌,抽出一张牌作为比较的元素,与前面的牌依次进行比较,小于继续往前比较,大于等于停下插入到当前位置。
图示:
void InsertSort(int* a, int n)
{
//控制所有次排序
for (int i = 0; i < n - 1; i++)
{
int end = i;//记录临时下标
int tmp = a[end + 1];//比较的元素
//一趟排序
while (end >= 0)
{
if (a[end] > tmp)//非升序
{
a[end + 1] = a[end];//前面的覆盖后面的
}
else
{
break;//是升序跳出本次循环
}
--end;//下标往前移动
}
a[end + 1] = tmp;//指向元素的下一个元素覆盖为tmp
}
}
注意:总共的排序次数是n-1趟,即end最多只能到倒数第二个元素,因为如果end为最后一个元素,那么end+1的位置就是越界的。
特性总结:
- 数组的元素越接近有序,该排序的效率越高
- 时间复杂度:O(N^2)
- 空间复杂度:O(1)
- 稳定
二、希尔排序
希尔排序与插入排序很像,单趟排序的思路基本相似,不同的是,插入排序的每次对比一个指向的元素是向前移动一个距离,希尔排序是移动gap个距离,从大到小,最后为1
void ShellSort(int* a, int n)
{
int gap = n;//先定义好初始距离
while (gap > 1)//限定条件
{
gap = gap / 3 + 1;//距离缩小
//类似插入排序,只是把1改成gap
for (int i = 0; i < n - gap; i++)
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end + gap] = a[end];
}
else
{
break;
}
end -= gap;
}
a[end + gap] = tmp;
}
}
}
注意:while循环的条件gap大于1并不是说gap不能为1,而是这里在前面的进入循环的时候就有可能为1了,记住gap是先缩小再使用的,进入循环时(还没有缩小)的gap是上次使用的gap
假如gap此时为2:,满足条件,进入while循环,2除3等于0,0加1等于1,下面使用的gap就是1
再进行循环的判断,如果条件不是大于1的话,而是大于等于1,那么gap为1可以进入循环,然后1除1等于1,1+1等于2,就死循环了。
特性总结:
- 希尔排序是对直接插入排序的优化
- 希尔排序的时间复杂度不好计算,因为gap的取值方式很多,时间复杂度暂时为:O(N ^1.3)——O(N ^2)
- 空间复杂度:O(1)
- 不稳定
原文地址:https://blog.csdn.net/2301_77459845/article/details/133746180
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_56942.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。