七大常见排序,你究竟懂几个?(上)(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)


④ 稳定性:不稳定



相关文章
十大排序引出的问题()
十大排序引出的问题()
43 0
|
1月前
|
存储 算法 安全
【C语言程序设计——选择结构程序设计】按从小到大排序三个数(头歌实践教学平台习题)【合集】
本任务要求从键盘输入三个数,并按从小到大的顺序排序后输出。主要内容包括: - **任务描述**:实现三个数的排序并输出。 - **编程要求**:根据提示在编辑器中补充代码。 - **相关知识**: - 选择结构(if、if-else、switch) - 主要语句类型(条件语句) - 比较操作与交换操作 - **测试说明**:提供两组测试数据及预期输出。 - **通关代码**:完整代码示例。 - **测试结果**:展示测试通过的结果。 通过本任务,你将掌握基本的选择结构和排序算法的应用。祝你成功!
36 4
|
存储
八大排序之图文详解(下)
八大排序之图文详解(下)
|
9月前
|
搜索推荐 算法 测试技术
数据结构:一篇拿捏十大排序(超详细版)
数据结构:一篇拿捏十大排序(超详细版)
68 0
|
9月前
|
算法 程序员
八大排序源码(含优化)
八大排序源码(含优化)
|
搜索推荐 Java
八大排序之图文详解(上)
八大排序之图文详解(上)
|
算法 搜索推荐 C++
理解实现八大排序(一)
理解实现八大排序
88 0
|
存储 搜索推荐 算法
理解实现八大排序(二)
理解实现八大排序
70 0
|
开发工具
【排序引论】第二章 单机排序问题
【排序引论】第二章 单机排序问题
65 0
【排序引论】第二章 单机排序问题