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


④ 稳定性:不稳定



相关文章
|
9月前
十大排序引出的问题()
十大排序引出的问题()
27 0
|
2月前
|
机器学习/深度学习 搜索推荐
【七大排序】最基础的排序——冒泡排序
【七大排序】最基础的排序——冒泡排序
29 4
|
3月前
|
算法 程序员
八大排序源码(含优化)
八大排序源码(含优化)
|
9月前
|
存储 移动开发 算法
八大排序(一)--------排序的基本概念与分类
八大排序(一)--------排序的基本概念与分类
47 0
|
存储 搜索推荐 算法
理解实现八大排序(二)
理解实现八大排序
39 0
|
算法 搜索推荐 C++
理解实现八大排序(一)
理解实现八大排序
65 0
|
存储 算法 搜索推荐
【经典八大排序】(2)
一 .直接插入排序 直接插入排序是从一段数据中将一个数据在合适的位置插入。
|
机器学习/深度学习 算法
【经典八大排序】(1)
一 .直接插入排序 直接插入排序是从一段数据中将一个数据在合适的位置插入。
|
机器学习/深度学习 存储 搜索推荐
七大排序经典排序算法
七大排序经典排序算法
72 0
七大排序经典排序算法
|
算法 搜索推荐
《十大排序算法》让你的思维流动起来。今天的主角又是排序思想你了解多少。每种算法的内容在代码中体现出来。
《十大排序算法》让你的思维流动起来。今天的主角又是排序思想你了解多少。每种算法的内容在代码中体现出来。
184 0
《十大排序算法》让你的思维流动起来。今天的主角又是排序思想你了解多少。每种算法的内容在代码中体现出来。