当前位置:网站首页>排序入门—插入排序和希尔排序
排序入门—插入排序和希尔排序
2022-07-24 09:03:00 【我的博尔赫斯】
目录
一.排序
排序是指按照关键字的递减或者递增顺序对一组记录重新进行排列的操作。
排序在生活中的应用场景很多,比如说在购物平台上我们筛选商品时常用的价格或者销量等等从低到高,从高到低,csdn上的排行榜等等本质上都是排序,所以学习排序是必要的。
二.排序的稳定性
当序列中的关键字各不相同时,那么排序的结果是唯一的。但是当序列中有相同的结果时,那么排序就有多种结果。举个例子,比如说有下面这一个数组:
int arr[] = {1, 3, 9, 3};如果对这个数组排序结果毫无疑问是1,3,3,9. 但是这两个3哪个排在前哪个排在后呢?如果经过排序后这两个3按照原来的相对顺序排列,那么我们就称这种排序方法是稳定的,否则是不稳定的。稳定与不稳定并没有绝对的优劣之分,各有各的适用场合。
三.直接插入排序
插入排序的思想是每一趟将一个待排序的元素插入到一个有序序列中的适当位置上,使得插入后该序列仍然有序,直到将所有元素插入为止。
这个思想很像我们打扑克牌,我们每次抓到牌都会插入到合适的位置使得我们手上的牌是有序的,直到抓完所有牌。

所以我们可以和斗地主一样,一次抓一张牌,然后插入到合适位置。依然拿上述数组(排成升序)举例:这个数组中的1就是我们抓的第一张牌,显而易见的是第一张牌不用排序,我们接着抓牌,抓到第二张牌是3,抓到后与1进行比较,3不比1小则排在后面,接着抓到9,9不比3小,排在后面,抓最后一张牌是3,3比9小则要进行比较:我们先拨开9这张牌,看到9的前面排着一个3,3不比3小,所以后面的这张3就放在前面那张3的后面,9的前面,那么抓牌就完毕了。这里因为篇幅问题所以把数组设置的简单一点,但是不管多复杂,过程都是这样的。
根据上面的思路我们可以这样想,将第一个数据想像成一个有序序列,然后将后一个元素插入到这个序列中,如果后一个元素比前一个元素小,那么就把前面一个元素往后挪动一个位置(拨开这张牌给后面的牌腾位置),继续向前比较,如果后一个元素比前一个元素大,那么就把后一个元素插入到前一个元素的后一个位置(把后一张3放到前一张3的后面,9的前面),就生成了一个新的有序序列,再将下一个元素插入,以此类推,直到将最后一个元素插入就完成了排序。可以看看动图来理解一下过程。

排序代码如下:
void Insert_sort(int* arr, int size)
{
for (int i = 0; i < size - 1; i++)
{
int end = i; //end记录有序序列的最后一个元素
int tmp = arr[end + 1];//将要插入的元素记录下来,因为挪动元素可能会覆盖掉要插入的元素
while (end >= 0)
{
if (tmp < arr[end])
{
arr[end + 1] = arr[end];
--end;
}
else
{
break; //如果后面元素比前面元素大,就跳出循环,不用再比
}
}
arr[end + 1] = tmp; //将要插入元素赋给后一个位置上
}
}#插入排序的复杂度分析
插入排序的时间复杂度: 最坏情况是逆序,这时候每个元素都要挪动,时间复杂度是O(n^2)。
空间复杂度:插入排序只需要开辟常数个变量,所以空间复杂度是O(1)。
四.希尔排序
对于插入排序,当序列本身比较有序时,这种排序的效率还是挺高的,但是如果处理的序列非常无序,时间效率则会极其低下。这时候有个叫希尔的人提出,可以先进行预排序,将序列变得有序些再进行插入排序。
所以希尔排序本质上仍是插入排序,其思路为:
1. 预排序
2. 插入排序
#预排序
采用分组插入的方法,将待排序序列分成几组,从而减少直接插入排序的数据量,对每组分别进行插入排序。注意对数据的分组并不是简单的“逐段分割”,而是将相隔某个增量的元素分成一组。

以这段序列为例,假如设定增量为2,则分组如下,同色线相连元素为一组。

要注意的是增量为1时就是直接插入排序,也就是说当增量越小,这个序列会变得越有序。所以我们可以在分组插入之后将增量逐渐减小,到最后增量为1时就完全有序了。
对于1组中的一个数据,可以写出如下代码进行插入:
int end = 0;
int gap = 3;
int tmp = arr[end + gap];
while (end >= 0)
{
if (arr[end] > tmp)
{
arr[end + gap] = arr[end];
end -= gap;
}
else
{
break;
}
}
arr[end + gap] = tmp;对于一组数据,则要套上一个循环
for (int i = 0; i < size - gap; i++)
{
int end = i;
int tmp = arr[end + gap];
while (end >= 0)
{
if (arr[end] > tmp)
{
arr[end + gap] = arr[end];
end -= gap;
}
else
{
break;
}
}
arr[end + gap] = tmp;
}解释:因为要访问end + gap位置的值,为了防止越界,所以i < size - gap。同时,用这层循环也可以走完所有的组,可以画图来感受一下,篇幅问题不加赘述。
控制gap的减少则需要再套上一层循环:
void Shellsort(int* arr, int size)
{
int gap = size; // 设置增量
while (gap > 1)
{
gap = gap / 3 + 1;
for (int i = 0; i < size - gap; i++)
{
int end = i;
int tmp = arr[end + gap];
while (end >= 0)
{
if (arr[end] > tmp)
{
arr[end + gap] = arr[end];
end -= gap;
}
else
{
break;
}
}
arr[end + gap] = tmp;
}
}
}用下列数组进行测试:
int arr[] = { 0,0,9,1,6,8056, 94656, 4568 };
Shellsort(arr, sizeof(arr) / sizeof(int));结果:

#希尔排序的时间复杂度比较难计算,笔者还没学,等下篇博文再向大佬们请教请教吧
边栏推荐
- Leetcode94 detailed explanation of middle order traversal of binary tree
- Houdini official HDA sidefx labs installation
- Xiaobai learns Jenkins - installation and quick start
- C # briefly describe the application of Richter's replacement principle
- Pulse netizens have a go interview question, can you answer it correctly?
- 脉脉网友出了道 Go 面试题,你能答对吗?
- 2、 Encapsulation and tool classes for adding, deleting, modifying and checking in midway
- Unity解决Package Manager“You seem to be offline”
- dp最长公共子序列详细版本(LCS)
- 链表——24. 两两交换链表中的节点
猜你喜欢
![[the first anniversary of my creation] love needs to be commemorated, so does creation](/img/89/2f8eec4f0a0bcf77d5a91179012899.png)
[the first anniversary of my creation] love needs to be commemorated, so does creation

Tiktok's "online celebrity" was poached by Amazon and broadcast on Amazon live platform

How to import CAD files into the map new earth and accurately stack them with the image terrain tilt model

Tongxin UOS developer account has supported uploading the HAP package format of Hongmeng application

Leetcode94-二叉树的中序遍历详解

【汇编语言实战】一元二次方程ax2+bx+c=0求解(含源码与过程截屏,可修改参数)

How to configure env.js in multiple environments in uni app

超全总结:Go语言如何操作文件

Office fallback version, from 2021 to 2019

Houdini official HDA sidefx labs installation
随机推荐
[translation] integration challenges in microservice architecture using grpc and rest
Un7.22: how to upload videos and pictures simultaneously with the ruoyi framework in idea and vs Code?
POI operation excel collation
Let's test 5million pieces of data. How to use index acceleration reasonably?
Functions of tiktok enterprise number
TCP triple handshake connection combing
5、 Use of environment variables in midway
Rank 3 and count from 0 to 9. How many times does each number appear in total, and how many times does each number appear in the tens of hundreds,
Take out the string in brackets
Leetcode102-二叉树的层序遍历详解
Android系统安全 — 5.2-APK V1签名介绍
Houdini notes
The solution of [an error occurred while trying to create a file in the destination directory: access denied] is prompted when installing the software
Shell script backup mongodb database
[FFH] openharmony gnawing paper growth plan -- Application of cjson in traditional c/s model
Unity C tool class arrayhelper
Tiktok live broadcast with goods marketing play
Run little turtle to test whether the ROS environment in the virtual machine is complete
Tiktok 16 popular categories, tiktok popular products to see which one you are suitable for?
One click openstack single point mode environment deployment - preliminary construction