七大常见排序,你究竟懂几个?(上)(1)

简介: 七大常见排序,你究竟懂几个?(上)

首先我们先来看一下基本的七大排序,今天我们先一起学习前四个:



q1.png

1、排序的概率及意义

排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起 来的操作。


稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记 录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍 在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。


内部排序:数据元素全部放在内存中的排序 。


外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据 的排序。


排序的运用:例如在淘宝购物时我们可以根据综合、销量、好评……进行排序。


2、直接插入和希尔排序的实现及分析

2.1.直接插入排序

①基本思想


直接插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐 个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。 实际中我们玩扑克牌时,就用了插入排序的思想:


q2.png


②直接插入排序


升序:

q3.png



#include<stdio.h>
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 (n > 1 && a[end] > tmp)
    {
    a[end + 1] = a[end];
    --end;
    }
    else
    {
    break;
    }
  }
  a[end + 1] = tmp;
  }
}
void PrintArray(int* a, int n)
{
  for (int i = 0; i < n; i++)
  {
  printf("%d ", a[i]);
  }
  printf("\n");
}
void TestInsertSort()
{
  int a[] = { 1, 3, 2, 6, 8, 7, 9, 4, 5, 0 };
  int size = sizeof(a) / sizeof(int);
  InsertSort(a, size);
  PrintArray(a, size);
}
int main()
{
  TestInsertSort();
  return 0;
}

思想: 刚开始执行时,end是数组第一个元素的下标,tmp存放的是end后面一个元素的值,让数组的end下标对应的值与tmp的值进行比较。若为升序,end下标对应的值如果大于tmp中存放的值就交换,然后让end--,然后while循环让end下标对应的值与tmp比较,若end<0就跳出,若end对应下标的值小于tmp要break(避免不必要的比较),跳出内循环后让end+1下标对应数组元素等于tmp。然后使end指向第二个元素的下标,同样的方法依次比较。


总结:


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


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


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


4. 稳定性:稳定


2.2希尔排序

希尔排序可以说是直接插入排序的进阶版。


希尔排序包含两部分:预排序(接近有序)、 直接插入排序(有序)


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

q4.png



观察以下排序:

w1.png


多组间隔为gap的预排序,gap有大变小


gap越大,大的数可以越快的到很后面,小的数可以越快到前面,预排序越不接近有序


gap越小,越接近有序


gap==1时就是直接插入排序


代码:

#define  _CRT_SECURE_NO_WARNINGS 1
#include
//希尔排序:直接插入排序的基础上的优化
//1、先进行预排序,让数组接近有序(分组排)
//2、直接插入排序
//时间复杂度为log₂N*N或者是log₃N*N
void ShellSort(int* a, int n)
{
  int gap = n;
  while (gap > 1)
  {
  //gap = gap / 2; //log₂N
  gap = gap / 3 + 1;//log₃N
  //gap>1时都是预排序  接近有序
  //gap==1时就是直接插入排序  有序
  //gap很大时,下面预排序时间复杂度O(n)
  //gap很小时,数组已经很接近有序了,这事差不多也是O(n)
  //把间隔为gap的多组数据同时排
  for (int i = 0; i
  {
    int end = i;
    int tmp = a[end + gap];
    while (end >= 0)
    {
    if (n > 1 && a[end] > tmp)
    {
      a[end + gap] = a[end];
      end -= gap;
    }
    else
    {
      break;
    }
    }
    a[end + gap] = tmp;
  }
  }
}
void PrintArray(int* a, int n)
{
  for (int i = 0; i < n; i++)
  {
  printf("%d ", a[i]);
  }
  printf("\n");
}
void TestInsertSort()
{
  int a[] = { 1, 3, 2, 6, 8, 7, 9, 4, 5, 0 };
  int size = sizeof(a) / sizeof(int);
  ShellSort(a, size);
  PrintArray(a, size);
}
int main()
{
  TestInsertSort();
  return 0;
}

希尔排序的特性总结:


① 希尔排序是对直接插入排序的优化


② 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,就是直接插入排序。它与直接插入排序的区别就是多了一个预排序,这样使时间效率更好


③ 希尔排序的时间复杂度不好计算,需要进行推导,推导出来平均时间复杂度: O(N^1.3— N^2)


④ 稳定性:不稳定



相关文章
|
API 容器
Flutter UI组件库(JUI)
Flutter UI组件库(JUI)
2459 17
|
消息中间件 监控 Java
【Kafka】kafka判断一个节点还活着?
【4月更文挑战第6天】【Kafka】kafka判断一个节点还活着?
|
Web App开发 数据采集 Python
让ChromeDriver 125顺利运行:解决找不到chromedriver.exe的技巧
本文介绍了如何解决Selenium使用ChromeDriver时遇到的版本不匹配问题,以及如何设置环境变量。同时,文章提供了示例代码,展示如何在Python中配置Selenium使用代理IP、设定User-Agent和Cookie进行网页抓取,以提高爬虫的效率和成功率。确保ChromeDriver与Chrome浏览器版本一致,将`chromedriver.exe`添加到环境变量,然后使用`Options`和`Proxy`类配置代理和浏览器选项,最后通过`webdriver.Chrome()`启动浏览器并执行抓取任务。
1119 0
让ChromeDriver 125顺利运行:解决找不到chromedriver.exe的技巧
动态粒子发射404网站HTML源码
动态粒子发射404网站HTML源码,粒子内容可以进行修改,默认是4,0数字还有一个页面不存在英文,可以自行修改,喜欢的朋友可以拿去使用,源码是html,记事本打开修改即可,鼠标双击可以运行
230 1
动态粒子发射404网站HTML源码
|
JavaScript
vue element-ui 菜单管理使用图标选择器组件
vue element-ui 菜单管理使用图标选择器组件
1192 0
|
JSON 关系型数据库 MySQL
穿越MySQL版本时光:5.7和8.0的差异全揭秘
穿越MySQL版本时光:5.7和8.0的差异全揭秘
8473 0
|
SQL 消息中间件 存储
【FlinkSQL实战系列】Flink SQL CDC 实时同步 Mysql 的 Binlog 数据到 kafka
什么是 CDC ? CDC,Change Data Capture,变更数据获取的简称,使用 CDC 我们可以从数据库中获取已提交的更改并将这些更改发送到下游,供下游使用。这些变更可以包括 INSERT,DELETE,UPDATE 等. 要解决什么问题 ?
|
前端开发 容器
CSS躬行记(10)——CSS方法论
  方法论是一个哲学术语,会对一系列具体的方法进行分析研究、系统总结并最终提出较为一般性的原则。CSS方法论是一种面向CSS、由个人和组织设计、已被诸多项目检验且公认有效的最佳实践。这些方法论都会涉及结构化的命名约定,并且在组织CSS时可提供相应的指南,从而提升代码的性能、可读性以及可维护性。本章会讲解三种CSS方法论:OOCSS、BEM和SMACSS。
|
Java
JAVA按顺序播放多个wav音频
用Java按顺序播放多个音频部件,不是同时播放。代码如下: List files = new ArrayList(); files.add("barcode_prefix.
3037 0