排序算法-插入/希尔排序

简介: 排序算法-插入/希尔排序

1 插入排序


1.1基本思想:

直接插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。


1.2直接插入排序:

当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与 array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移。


直接插入排序的特性总结:

1. 元素集合越接近有序,直接插入排序算法的时间效率越高

2. 时间复杂度:O(N^2)

3. 空间复杂度:O(1),它是一种稳定的排序算法

4. 稳定性:稳定

写排序算法的一种好习惯就是先写一个单趟排序,再使用循环来实现整体。假设实现一个升序,首先创建一个变量end=0,然后tmp保存a[end+1]的值,写一个while循环,结束条件是end<0,进入循环判断tmp和a[end]的大小,如果tmp小则将a[end]的值覆盖到a[end+1],然后end--,跳出循环,此时将tmp插入到a[end+1]也就是a[0]这个位置。如果tmp>=a[end],直接退出循环。然后将tmp的值插入到a[end+1]这个位置。然后最外层套一层循环,每次单趟结束后end++。

c569210c37fe479e8620f36d87982b04.png

// 插入排序
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 (tmp < a[end])
    {
    a[end + 1] = a[end];
    }
    else
    {
    break;
    }
    end--;
  }
  a[end + 1] = tmp;
  }
}


2.希尔排序( 缩小增量排序 )


希尔排序法又称缩小增量法。希尔排序法的基本思想是: 先选定一个整数,把待排序文件中所有记录分成个 组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后取重复上述分组和排序的工 作。当到达 =1 时,所有记录在统一组内排好序 。

假设将下列数组分为gap=3组,先完成单趟,将end=0,tmp保存a[end+gap]这个位置的值,进行比较,tmp大则将a[end]覆盖到[end+gap]这个位置,然后end-gap,退出循环,将tmp插入到a[end+gap]这个位置,也就是a[0]这个位置。然后写一个循环控制end的位置,每次end+gap。到这里就完成了黑色的这一组数据,此时可以再套一层循环控制住红色和蓝色的这两组数据。

dfe7138bac1f4affb368692bc8314a3f.png

void ShellSort1(int* a, int n)
{
  int gap = n;
  while (gap > 1)
  {
  gap = gap / 3 + 1;
  for (int j = 0; j < gap; j++)
  {
    for (int i = j; i < n - gap; i += gap)
    {
    int end = i;
    int tmp = a[end + gap];
    while (end >= 0)
    {
      if (tmp < a[end])
      {
      a[end + gap] = a[end];
      end -= gap;
      }
      else
      {
      break;
      }
    }
    a[end + gap] = tmp;
    }
  }
  }
}

当然也可以在单趟外只套一层循环,巧妙地控制i。

void ShellSort2(int* a, int n)
{
  int gap = n;
  while (gap > 1)
  {
  //gap = gap / 2;
  gap = gap / 3 + 1;
  for (int i = 0; i < n - gap; ++i)
  {
    int end = i;
    int tmp = a[end + gap];
    while (end >= 0)
    {
    if (tmp < a[end])
    {
      a[end + gap] = a[end];
      end -= gap;
    }
    else
    {
      break;
    }
    }
    a[end + gap] = tmp;
  }
  }
}

希尔排序的特性总结:

1. 希尔排序是对直接插入排序的优化。

2. 当 gap > 1 时都是预排序,目的是让数组更接近于有序。当 gap == 1 时,数组已经接近有序的了,这样就 会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。

3. 希尔排序的时间复杂度不好计算,因为 gap 的取值方法很多,导致很难去计算,因此在好些树中给出的 希尔排序的时间复杂度都不固定。

9a1e468ba7ec4ac6b715d2edbfca3548.png

4. 稳定性:不稳定  。


今天的分享到这里就结束了,感谢大家的阅读!

相关文章
|
7月前
|
算法 搜索推荐 Java
数据结构与算法(Java篇)笔记--希尔排序
数据结构与算法(Java篇)笔记--希尔排序
|
2月前
|
算法 搜索推荐 Shell
数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
33 1
|
6月前
|
算法 搜索推荐
数据结构算法--6 希尔排序和计数排序
**希尔排序**是插入排序的改进版,通过分组插入来提高效率。它逐步减少元素间的间隔(增量序列),每次对每个间隔内的元素进行插入排序,最终增量为1时进行最后一次直接插入排序,实现整体接近有序到完全有序的过程。例如,对数组`5, 7, 4, 6, 3, 1, 2, 9, 8`,先以间隔`d=4`排序,然后`d=2`,最后`d=1`,完成排序。计数排序则适用于0到100的数值,通过统计每个数出现次数,创建对应计数数组,再根据计数重建有序数组,时间复杂度为`O(n)`。
|
5月前
|
算法 搜索推荐 Shell
|
6月前
|
人工智能 搜索推荐 JavaScript
心得经验总结:排序算法:插入排序法(直接插入法和希尔排序法)
心得经验总结:排序算法:插入排序法(直接插入法和希尔排序法)
46 0
|
6月前
|
机器学习/深度学习 搜索推荐 算法
【C/排序算法】:直接插入排序和希尔排序
【C/排序算法】:直接插入排序和希尔排序
49 0
|
6月前
|
搜索推荐
排序算法---希尔排序---详解&&代码
排序算法---希尔排序---详解&&代码
|
6月前
|
算法 Shell C语言
数据结构与算法——希尔排序(引例、希尔增量序列、原始希尔排序、代码、时间复杂度、Hibbard增量序列、Sedgewick增量序列)
数据结构与算法——希尔排序(引例、希尔增量序列、原始希尔排序、代码、时间复杂度、Hibbard增量序列、Sedgewick增量序列)
71 0
|
7月前
|
存储 算法 搜索推荐
【数据结构与算法】:插入排序与希尔排序
欢迎大家来到初阶数据结构的最后一小节:排序
【数据结构与算法】:插入排序与希尔排序
|
7月前
|
搜索推荐 算法 Shell
【数据结构与算法】直接插入排序和希尔排序
【数据结构与算法】直接插入排序和希尔排序