目录
前言
哈喽,小伙伴们大家好。排序一直是算法中的一个重要内容,对于计算机初学者有一定的挑战。相信很多刚刚接触排序的小伙伴除了冒泡排序掌握的非常熟练之外,对其它的排序方法都是一知半解(反正我刚开始学的是这样hhh)。那么今天我将把几种常用的排序进行汇总,对原理以及实现方法进行讲解,希望能给大家带来帮助。
一、常见的排序方法
排序概念:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
常见的排序方法:
二、插入排序
1.插入排序的思想
相信大家都应该玩过扑克牌吧,在我们玩斗地主的时候,为了方便看牌,常常会一边摸牌一边把牌按大小顺序排列起来,在这个过程中其实就用到了插入排序的思想。我们不妨一起回忆一下平常在摸牌的时候是怎样进行排序的。
首先,我们摸了一张5放到手里。然后又摸到了一张7,用7和5去比较,7比5大所以我们把它放到了5的右边。然后又摸到了一张6,6和7比较,6比7小,6继续和5比较,6比5大,放到5的右边……在这之后我们每摸一张牌都和手中原来的牌从右向左依次比较,直到找到比摸到的牌小的牌,然后把摸到的牌插入到它的右边,这个过程就是插入排序的思想。
2、直接插入排序
2.1直接插入排序的实现
按照我们上面描述的思想,我们可以进行实现,代码如下:
insert_sort(int* a, int n)
{
for (int i = 0; i < n - 1; i++)
{
//[0,end]有序,把a[end+1]插入进去
int end = i;
int temp = a[end + 1];
while (end >= 0)
{
if (a[end]>temp)
{
a[end + 1] = a[end];
end--;
}
else
{
break;
}
}
a[end + 1] = temp;
}
}
2.2插入排序特点
- 时间复杂度为O(N^2)
- 元素集合越接近有序,插入排序时间效率越高。在有序的情况下时间复杂度为O(N)
- 空间复杂度:O(1)
3、希尔排序
3.1希尔排序介绍
简介:希尔排序是对直接插入排序的优化。通过上面的介绍我们知道,在越接近有序的情况下,插入排序的效率越高。既然如此,就有人想到,在进行排序之前,能不能先进行一下预排序,使元素集合处在接近有序的状态来提高效率呢?于是希尔排序就诞生了。
思想:希尔排序又称缩小增量法,基本思想是把一个元素集合分为gap组,每个组之间元素的距离为gap,然后分别对几个组进行排序。排序完成后再缩小gap,再重新分组进行排序,重复此过程。直到gap为1,预排序完成,再进行最后的插入排序。
3.2希尔排序实现
代码如下:
shell_sort(int* a,int n)
{
int gap = n;
while (gap > 1)
{
gap = gap / 3 + 1;//保证最后一次gap是1
for (int i = 0; i < n - gap; i++)
{
int end = i;
int temp = a[end + gap];
while (end >= 0)
{
if (a[end] > temp)
{
a[end + gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = temp;
}
}
}
希尔排序的特性总结:
- 希尔排序是对直接插入排序的优化。
- 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
- 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,我们可以参考一下书中给出的。
三、选择排序
1、基本思想
选择排序的思想非常简单粗暴,即每次从要排序的集合中选出一个最大或最小的数放在序列起始位置,重复此操作,直到序列中的全部元素被排完。
2、直接选择排序
根据选择排序的原理,我们不难把代码实现出来。
void select_sort(int* a, int n)
{
int begin = 0;
int end = n - 1;
//最小的放到队头,最大的放到队末
while (begin < end)
{
int max = begin, min = begin;
for (int i = begin; i