c++实现排序(简单插入,希尔,选择,快速,冒泡,堆排)

简单插入排序

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

代码如下:

时间复杂度:最好情况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;
      }
   }
}

时间: 2024-11-05 15:49:46

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

简单排序:插入,选择和冒泡

void selectsort(int a[],int n) // 选择排序的思路就是每次找到当前序列中最小的元素,然后交换 { // 就是选择最小的,然后交换 int i,j,flag; for(i = 0;i<n;i++) { flag = i; //当前元素 for(j = i+1;j<n;j++) { if(a[j]<a[flag]) flag = j; //在剩下未排序的数组中找到最小元素的下标 } int temp = a[i]; //交换当前元素和最小元素. a[i] =

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

本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排序.快速排序(重点).堆排序.归并排序等等.看下图: 给定数组:int data[] = {9,2,7,19,100,97,63,208,55,78} 一.直接插入排序(内部排序.O(n2).稳定) 原理:从待排序的数中选出一个来,插入到前面的合适位置. [java] view plain copy

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

排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排序.快速排序(重点).堆排序.归并排序等等.看下图: 给定数组:int data[] = {9,2,7,19,100,97,63,208,55,78} 一.直接插入排序(内部排序.O(n2).稳定) 原理:从待排序的数中选出一个来,插入到前面的合适位置. package com.xtfggef.algo.sort; public

面试题---各种排序。插入,选择,冒泡,shell,堆,快排

#include<iostream> #include<string> #include<vector> using namespace std; void swap(int a[], int i, int j); void insert_sort(int a[], int n) { for (int i = 1; i < n; i++) { int temp = a[i], j = i; while (j&&temp < a[j - 1])

排序算法之希尔、归并、堆和基数排序

//希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.但希尔排序是非稳定排序算法. 希尔排序是基于插入排序的以下两点性质而提出改进方法的 : 1. 插入排序在对几乎已经排好序的数据操作时,效率高,既可以达到线性排序的效率 2. 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位 希尔排序的基本思想是 : 先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时, 再堆全体记录进行依次直接插入排序. 算法步骤 : 1:

自己动手实现数据结构——排序算法2 (希尔、快速、堆)(C++实现)

希尔排序 又称缩小增量排序 先给数组设定一个增量,一般数组长度为len,同常将增量设为increment = len/2,increment每次缩小为原来的1/2. 1.通过这个增量给数组里的数分组:例如 0,0+increment, 0+2*increment,... 为一组   1,1+increment, 1+2*increment,...为另外一组. 2.对于每一个组通过插入算法进行排序.(前面已经写了折半插入排序,这里写的是普通插入排序) 3.increment = increment

1. 算法 -- 排序(插入,冒泡,希尔,快速,选择)

1.  插入排序===================================================== 算法思想简单描述: 在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的.如此反复循环,直到全部排好顺序. 直接插入排序是稳定的.算法时间复杂度O(n2)--[n的平方] 一般来说,插入排序都采用in-place在数组上实现.具体算法描述如下:1.从第一个元素开始,该元素可以认为已经被排序

排序算法-冒泡、插入、归并、希尔、快速、选择--代码总结

冒泡排序代码: #include <iostream> #include <string> using namespace std; template<class ItemType> void bubbleSort(ItemType theArray[], int n) { bool sorted = false; // False when swaps occur int pass = 1; while (!sorted && (pass < n

排序 之 冒泡排序 简单选择排序 直接插入排序 希尔排序

排序的基本概念 假设含有n个记录的序列为{r1,r2,--,rn},其相应的关键字分别为{k1,k2,--,kn},需确定1,2,--,n的一种排序p1,p2,--,pn,使其相应的关键字满足kp1≤kp2≤--≤kpn非递减(或非递增)关系,即使得序列称为一个按关键字有序的序列{rp1,rp2,--,rpn},这样的操作就称为排序. 排序的稳定性 假设ki=kj(1≤i≤n,1≤j≤n,i≠j),且在排序前的序列中ri领先于rj(即i<j).如果排序后ri仍领先于rj,则称所用的排序方法是稳定

排序算法(一)3种简单排序(选择,冒泡,插入)

排序是数据处理中十分常见且核心的操作,虽说实际项目开发中很小几率会需要我们手动实现,毕竟每种语言的类库中都有n多种关于排序算法的实现.但是了解这些精妙的思想对我们还是大有裨益的.本文简单温习下最基础的三类算法:选择,冒泡,插入. 先定义个交换数组元素的函数,供排序时调用 /** * 交换数组元素 * @param arr * @param a * @param b */ public static void swap(int []arr,int a,int b){ arr[a] = arr[a]