简单插入排序

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

代码如下:

时间复杂度:最好情况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. 混合式APP开发中中间件方案Rexsee

    发现Rexsee时,他已经一年多没有更新过了,最后版本是2012年的. 他的实现思路是通过Android自带的Java - Javascript 桥机制,在WebView中的JavaScript同Ja ...

  2. jsp中自定义Taglib案例

    一.使用TagSupport类案例解析 1.自定义Tag使用jdbc连接mysql数据库 1.1定义标签处理器类 package com.able.tag; import java.sql.Conne ...

  3. 股票价格涨跌预测—基于KNN分类器

    code{white-space: pre;} pre:not([class]) { background-color: white; }if (window.hljs && docu ...

  4. Exchange 2013 申请证书

    最近在了解Exchange2013,Exchange2013相对于Lync安装相对容易一点,安装完成并不代表就可以用了,还要一些基本的配制,首先介绍一下如何从证书服务器申请 CA. 一.DNS 创建解 ...

  5. 微信CRM六大模块的详解

    微信团队一直强调企业微信的主要功能是服务而非营销工具,微信5.0将公众号区分为服务号和订阅号,10月底平台为服务号开放高级接口,包括客服接口.网页授权等,可见服务是微信公众号的核心价值和方向.前一阵很 ...

  6. Upgrading or Redeploying SharePoint 2010 Workflows

    While creating several State Machine SharePoint 2010 workflows using visual studio for a client I ha ...

  7. Mac下安装Django

    用到一个Python写的后台服务,需要用到Django,参考Django安装文档,配置过程如下: 1.下载一个用来安装和管理Python包的工具“pip”; 2.下载完成后,运行安装脚本,注意需要管理 ...

  8. KVO的使用

    KVO的使用 KVO是一种设计模式,名为观察者. addObserver:forKeyPath:options:context: 通知其他对象的方法,这个方法在NSObject中就已经申明了,也就是说 ...

  9. LeetCode 8 String to Integer (string转int)

    题目来源:https://leetcode.com/problems/string-to-integer-atoi/ Implement atoi to convert a string to an ...

  10. 深入PHP内核之面向对象总结

    很久以前看过的,今天总结一下 一.PHP中创建一个类 在PHP中创建一个简单的类是这样的: <?php $obj = new test($url) ?> 二.zend_class_entr ...