简单插入排序

适用于记录较少且基本有序的记录。算法思想:给定一个存在分界线的序列,分界线左边有序,右边无序,依次将右边的没排序的数与左边序列进行比较,插入相应位置,再对分界线做出相应调整,下面用图来说明。

代码如下:

时间复杂度:最好情况O(n),最坏O(n^2)。

希尔排序

希尔排序是改进后的简单插入排序。算法思想:将序列分组排序,最后在进行一次简单插入排序。

至于如何分组,下面我将用图向大家展示

这些数的下标从0开始,即0,3 ,6,9为一组,1,4,7为一组,2,5,8为一组。也就是gap%3下标相等的为一组。gap=gap/3+1.

代码如下:

void ShellSort(int *a, size_t size)    //希尔排序
{
  assert(a);
  int gap = size;
  while (gap > 1)
  {
      gap = gap / 3 + 1;
      for (int i = gap; i < size; ++i)
     {
       int index = i;
       int tem = a[index];
       int end = index - gap;
       while (end >= 0 && tem < a[end])
       {
          a[end + gap] = a[end];
          end -= gap;
       }
       a[end + gap] = tem;
     }
  }
}

时间复杂度为O(n^1.5)

选择排序

算法思想:每次循环找到最小值,并交换。

代码如下:

void SelectSort(int *a, size_t size)
{
   assert(a);
   for (int i = 0; i < size; ++i)
   {
      int minindex = i;
      int tem;
      for (int j = i + 1; j < size; ++j)
      {
         if (a[j] < a[minindex])
         {
            minindex = j;
            tem = a[minindex];
            a[minindex] = a[i];
            a[i] = tem;
         }
      }
   }
}

时间复杂度O(n^2)

快速排序

算法思想:选取key,将key调整到一个合理的位置,使得左边全部小于key,右边全部大于key;

如何将key调整到合适位置,这里用到三数取中的方法。

注意:如果序列基本有序或序列个数较少,则可以采用简单插入排序,因为快速排序对于这些情况效率不高;

代码如下:

int GetMidIndex(int *a, int left, int right)     /////////三数取中/////////
{
   assert(a);
   int mid=left+(right-left)/2;
   if (left < right)
   {
      if (a[mid] < a[left])
         return left;
      else if (a[mid] < a[right])
         return mid;
      else
         return right;
   }
   else
   {
      if (a[mid] < a[right])
         return right;
      else if (a[mid] < a[left])
         return mid;
      else
         return left;
   }
}

int PartionSort(int *a, int left, int right)
{
   int midIndex = GetMidIndex(a, left, right);
   swap(a[midIndex], a[right]);
   int cur = left;
   int prev = left - 1;
   while (cur < right)
   {
      if (a[cur] < a[right] && ++prev != cur)
      {
         swap(a[cur], a[prev]);
      }
      ++cur;
   }
   ++prev;
   swap(a[prev], a[right]);
   return prev;
}

void QuickSort(int *a,int left,int right)
{
   assert(a);
   int size = right - left + 1;
   if (right - left > 13)        //////////优化:当长度大于13时采用快排,小于13则退化为简单插入排序////////////
   {
      int boundary = PartionSort(a, left, right);
      QuickSort(a, left, boundary - 1);
      QuickSort(a, boundary + 1, right);
   }
   else
      InsertSort(a, size);   /////简单插入排序
}

冒泡排序

算法思想:两两比较再交换,一趟排序下来只能找到一个最大,其余都是乱序,再重复这样做就可以按照从小到大的顺序排下来。

代码如下:

void BubbleSort(int *a, size_t size)
{
   assert(a); 
   for (int i = 0; i < size; i++)
   {
      for (int j = 0; j = size - 1 - i; j++)
      {
         if (a[j] > a[j + 1])
         {
            int tem = a[j + 1];
            a[j + 1] = a[j];
            a[j] = tem;
         }
      }
   }
}

以上冒泡排序有一个效率问题,当序列基本接近有序时,则不需要进行排序,以上代码则会进行不断的比较,影响效率,因此做以下改进,设一个布尔型变量flag,

如果一次循环中没有交换过元素,则说明已经排好序.

优化:

void BubbleSort(int *a, size_t size)
{
   assert(a);

bool flag=true;
   for (int i = 0; i < size; i++)
   {

      bool flag=false;
      for (int j = 0; j = size - 1 - i; j++)
      {
         if (a[j] > a[j + 1])
         {
            int tem = a[j + 1];
            a[j + 1] = a[j];
            a[j] = tem;

          bool flag=true;
         }
      }
   }
}

堆排序

算法思想:将待排序列建成大堆,再将堆顶数据与堆的最后一个叶子节点的数据交换,再重新调整为大堆,每次堆的数据个数减1。

依次类推......

代码如下:

void HeapSort(int *a, size_t size)    //堆排序
{
   assert(a);
   for (int i = (size - 2) / 2; i >= 0; --i)
   {
      Adjustdown(a, size, i);
   }
   for (int i = 0; i < size; ++i)
   {
      swap(a[0], a[size - i - 1]);
      Adjustdown(a, size - i - 1, 0);
   }
}

/////////建大堆/////////

void Adjustdown(int *a, size_t size, int root)
{
   int child = 2 * root + 1;
   while (child < size)
   {
      if (child + 1 < size && a[child + 1] > a[child])
         {
         ++child;
      }
      if (a[child]>a[root])
      {
         swap(a[child], a[root]);
         root = child;
         child = 2 * root + 1;
      }
      else
      {
        break;
      }
   }
}

c++实现排序(简单插入,希尔,选择,快速,冒泡,堆排)的更多相关文章

  1. Java常见的几种排序算法-插入、选择、冒泡、快排、堆排等

    本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排 ...

  2. 排序算法练习--JAVA(:内部排序:插入、选择、冒泡、快速排序)

    排序算法是数据结构中的经典算法知识点,也是笔试面试中经常考察的问题,平常学的不扎实笔试时候容易出洋相,回来恶补,尤其是碰到递归很可能被问到怎么用非递归实现... 内部排序: 插入排序:直接插入排序 选 ...

  3. 用Python实现十大经典排序算法-插入、选择、快速、冒泡、归并等

    本文来用图文的方式详细讲解了Python十大经典排序算法 —— 插入排序.选择排序.快速排序.冒泡排序.归并排序.希尔排序.插入排序.桶排序.基数排序.计数排序算法,想要学习的你们,继续阅读下去吧,如 ...

  4. 2020-03-25:快排、堆排和归并都是O(nlog n)的算法,为何JDK选择快速排序?

    福哥答案2020-03-26: 口诀如下:冒选插希快 堆归计桶基(冒泡,选择,插入,希尔,快速,堆,归并,计数,桶,基数)冒线 平平 稳常小选平 平平 不常小插线 平平 稳常序希线 四组 不常组快四 ...

  5. java 基础排序(冒泡、插入、选择、快速)算法回顾

    java 基础排序(冒泡.插入.选择.快速)算法回顾 冒泡排序 private static void bubbleSort(int[] array) { int temp; for (int i = ...

  6. 【PHP数据结构】插入类排序:简单插入、希尔排序

    总算进入我们的排序相关算法的学习了.相信不管是系统学习过的还是没有系统学习过算法的朋友都会听说过许多非常出名的排序算法,当然,我们今天入门的内容并不是直接先从最常见的那个算法说起,而是按照一定的规则一 ...

  7. 八大排序方法汇总(选择排序,插入排序-简单插入排序、shell排序,交换排序-冒泡排序、快速排序、堆排序,归并排序,计数排序)

    2013-08-22 14:55:33 八大排序方法汇总(选择排序-简单选择排序.堆排序,插入排序-简单插入排序.shell排序,交换排序-冒泡排序.快速排序,归并排序,计数排序). 插入排序还可以和 ...

  8. 选择排序—简单选择排序(Simple Selection Sort)

    基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素 ...

  9. 选择排序—简单选择排序(Simple Selection Sort)原理以及Java实现

    基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素 ...

  10. [译]async/await中使用阻塞式代码导致死锁 百万数据排序:优化的选择排序(堆排序)

    [译]async/await中使用阻塞式代码导致死锁 这篇博文主要是讲解在async/await中使用阻塞式代码导致死锁的问题,以及如何避免出现这种死锁.内容主要是从作者Stephen Cleary的 ...

随机推荐

  1. tomcat+webservice实现简单的web服务远程调用接口

    1,准备工作:    ①需要使用到jaxws的一系列架包,网址:http://jax-ws.java.net,我下的是比较新的一个版本(下载好以后吧架包发在lib下),②webservice的一个工具 ...

  2. linux查看rpm包创建的所有目录和文件

    有不少时候,我们需要查看某个rpm创建的所有目录和文件,出于了解程序结构或者其他目的,但是对于这个rpm包我们又不怎么熟悉,这个时候可以通过rpm -ql rpm名称查看. 但是rpm名称有可能又忘了 ...

  3. windows 7文件误删shift+delete后找回

    昨天要还电脑了,结果脑子一抽,某个目录还没拷贝,shift+delete了整个目录,删除到一半,完了...我的源码都在里面还没出来啊...这TMD要命啊... 赶紧搜了一把,windows文件误删恢复 ...

  4. android: DOC命令:查看后台运行的activity:

    DOC命令:查看后台运行的activity: adb shell dumpsys activity running activity: 模拟器曾经运行过的 activity:

  5. Java Map按Value排序

    Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等. TreeMap:基于红黑树(Red-Black tree)的 Nav ...

  6. mvc与三层结构终极区别

    http://blog.csdn.net/csh624366188/article/details/7183872 http://www.cnblogs.com/zhhh/archive/2011/0 ...

  7. 关于C#中Environment.OSVersion判断操作系统及Win10上的问题

    我们都知道在C#中可以通过Environment.OSVersion来判断当前操作系统,下面是操作系统和主次版本的对应关系: 操作系统 主版本.次版本 Windows 10 10.0* Windows ...

  8. ASP.NET MVC another entity of the same type already has the same primary key value

    ASP.NET MVC项目 Repository层中,Update.Delete总是失败 another entity of the same type already has the same pr ...

  9. 来自 CORS 预检通道的 CORS 头 'Access-Control-Allow-Headers' 的令牌 'appkey' 无效)。

    1.服务端: web.config文件中: <system.webServer> <httpProtocol> <customHeaders> <add na ...

  10. The system clock has been set back more than 24 hours

    由于破解调试需要,更改了系统时间,打开ArcMap会出现"The system clock has been set back more than 24 hours"的错误,原因是 ...