c语言实现插入排序、冒泡排序、选择排序、快速排序、堆排序、归并排序、希尔排序示例,需要的朋友可以参考下
 
 

实现以下排序

插入排序O(n^2)

冒泡排序 O(n^2)

选择排序 O(n^2)

快速排序 O(n log n)

堆排序 O(n log n)

归并排序 O(n log n)

希尔排序 O(n^1.25)

1.插入排序 O(n^2)

一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:
⒈ 从第一个元素开始,该元素可以认为已经被排序
⒉ 取出下一个元素,在已经排序的元素序列中从后向前扫描
⒊ 如果该元素(已排序)大于新元素,将该元素移到下一位置
⒋ 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
⒌ 将新元素插入到下一位置中
⒍ 重复步骤2~5
如果比较操作的代价比交换操作大的话,可以采用二分查找法来减少比较操作的数目。该算法可以认为是插入排序的一个变种,称为二分查找排序。

复制代码代码如下:
void insert_sort(int* array,unsignedint n){
    int i,j;
    int temp;
    for(i=1;i<n;i++){
        temp=*(array+i);
        for(j=i;j>0&&*(array+j-1)>temp;j--){
            *(array+j)=*(array+j-1);
        }
        *(array+j)=temp;
    }
}

2.冒泡排序 O(n^2)

冒泡排序算法的运作如下:
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

复制代码代码如下:
#include<stdio.h>
#defineSIZE8
void bublle_sort(int a[],int n){//n为数组a的元素个数
    int i,j,temp;
    for(j=0;j<n-1;j++)
       for(i=0;i<n-1-j;i++)
          if(a[i]>a[i+1]){//数组元素大小按升序排列
             temp=a[i];
             a[i]=a[i+1];
             a[i+1]=temp;
          }
      }
int main(){
    int number[SIZE]={95,45,15,78,84,51,24,12};
    int i;
    bublle_sort(number,SIZE);
    for(i=0;i<SIZE;i++){
       printf("%d",number[i]);
    }
    printf("\n");

3.选择排序 O(n^2)

复制代码代码如下:
  void select_sort(int * a, int n){  
           register int i, j, min, t;
           for( i =0; i < n -1; i ++) { 
                 min = i; //查找最小值 
                for( j = i +1; j < n; j ++)
                       if( a[min] > a[j]) 
                           min = j; //交换
                       if(min != i) {
                           t = a[min]; 
                          a[min] = a[i]; 
                          a[i] = t; 
                       }
                   } 
         }

4.快速排序 O(n log n)

复制代码代码如下:
void QuickSort(int a[],int numsize){//a是整形数组,numsize是元素个数
     int i=0,j=numsize-1;
     int val=a[0];//指定参考值val大小
     if(numsize>1){//确保数组长度至少为2,否则无需排序
         while(i<j{//循环结束条件
            for(;j>i;j--)//从后向前搜索比val小的元素,找到后填到a[i]中并跳出循环
               if(a[j]<val){
                 a[i]=a[j];break;
            }
            for(;i<j;i++)//从前往后搜索比val大的元素,找到后填到a[j]中并跳出循环
              if(a[i]>val){
                  a[j]=a[i];break;
              }
         }
         a[i]=val;//将保存在val中的数放到a[i]中
         QuickSort(a,i);//递归,对前i个数排序
         QuickSort(a+i+1,numsize-1-i);//对i+1到numsize这numsize-1-i个数排序
    }
}

5. 堆排序 O(n log n)
n个关键字序列Kl,K2,…,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质):
(1)ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n),当然,这是小根堆,大根堆则换成>=号。//k(i)相当于二叉树的非叶子结点,K(2i)则是左子节点,k(2i+1)是右子节点.
若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。

复制代码代码如下:
// array是待调整的堆数组,i是待调整的数组元素的位置,nlength是数组的长度
//本函数功能是:根据数组array构建大根堆
void HeapAdjust(int array[], int i, int nLength)
{
    int nChild;
    int nTemp;
    for (nTemp = array[i]; 2 * i + 1 < nLength; i = nChild)
    {
        // 子结点的位置=2*(父结点位置)+ 1
        nChild = 2 * i + 1;
        // 得到子结点中较大的结点
        if ( nChild < nLength-1 && array[nChild + 1] > array[nChild])
            ++nChild;
        // 如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点
        if (nTemp < array[nChild])
        {
            array[i] = array[nChild];
            array[nChild]= nTemp;
        }
        else
        // 否则退出循环
            break;
    }
}

// 堆排序算法
void HeapSort(int array[],int length)
{  
    int tmp;
    // 调整序列的前半部分元素,调整完之后第一个元素是序列的最大的元素
    //length/2-1是第一个非叶节点,此处"/"为整除
    for (int i = floor(length -1)/ 2 ; i >= 0; --i)
        HeapAdjust(array, i, length);
    // 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
    for (int i = length - 1; i > 0; --i)
    {
        // 把第一个元素和当前的最后一个元素交换,
        // 保证当前的最后一个位置的元素都是在现在的这个序列之中最大的
      ///  Swap(&array[0], &array[i]);
          tmp = array[i];
          array[i] = array[0];
          array[0] = tmp;
        // 不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值
        HeapAdjust(array, 0, i);
    }
}

6.归并排序 O(n log n)

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个    有序表合并成一个有序表,称为二路归并。

复制代码代码如下:
//归并操作
void Merge(int sourceArr[], int targetArr[], int startIndex, int midIndex, int endIndex)
{
    int i, j, k;
    for(i = midIndex+1, j = startIndex; startIndex <= midIndex && i <= endIndex; j++)
    {
        if(sourceArr[startIndex] < sourceArr[i])
        {
            targetArr[j] = sourceArr[startIndex++];
        }
        else
        {
            targetArr[j] = sourceArr[i++];
        }
    }

if(startIndex <= midIndex)
    {
        for(k = 0; k <= midIndex-startIndex; k++)
        {
            targetArr[j+k] = sourceArr[startIndex+k];
        }
    }

if(i <= endIndex)
    {
        for(k = 0; k <= endIndex- i; k++)
        {
            targetArr[j+k] = sourceArr[i+k];
        }
    }
}
//内部使用递归,空间复杂度为n+logn
void MergeSort(int sourceArr[], int targetArr[], int startIndex, int endIndex)
{
    int midIndex;
    int tempArr[100]; //此处大小依需求更改
    if(startIndex == endIndex)
    {
        targetArr[startIndex] = sourceArr[startIndex];
    }
    else
    {
        midIndex = (startIndex + endIndex)/2;
        MergeSort(sourceArr, tempArr, startIndex, midIndex);
        MergeSort(sourceArr, tempArr, midIndex+1, endIndex);
        Merge(tempArr, targetArr,startIndex, midIndex, endIndex);
    }
}

//调用
int _tmain(int argc, _TCHAR* argv[])
{
    int a[8]={50,10,20,30,70,40,80,60};
    int b[8];
    MergeSort(a, b, 0, 7);
    for(int i = 0; i < sizeof(a) / sizeof(*a); i++)
        cout << b[i] << ' ';
    cout << endl;
    system("pause");
    return 0;
}

7.希尔排序 O(n^1.25)
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

复制代码代码如下:
void ShellSort(int a[], int n){
     int d, i, j, temp;
     for(d = n/2;d >= 1;d = d/2){
        for(i = d; i < n;i++){
            temp = a[i];
            for(j = i - d;(j >= 0) && (a[j] > temp);j = j-d){
                a[j + d] = a[j];
            }
            a[j + d] = temp;
       }
    }
}

排序算法 c实现的更多相关文章

  1. JavaScript实现常用的排序算法

    ▓▓▓▓▓▓ 大致介绍 由于最近要考试复习,所以学习js的时间少了 -_-||,考试完还会继续的努力学习,这次用原生的JavaScript实现以前学习的常用的排序算法,有冒泡排序.快速排序.直接插入排 ...

  2. 排序算法----基数排序(RadixSort(L))单链表智能版本

    转载http://blog.csdn.net/Shayabean_/article/details/44885917博客 先说说基数排序的思想: 基数排序是非比较型的排序算法,其原理是将整数按位数切割 ...

  3. 常见排序算法(附java代码)

    常见排序算法与java实现 一.选择排序(SelectSort) 基本原理:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换:接着对不包括第一个记录以外的其他 ...

  4. 几大排序算法的Java实现

    很多的面试题都问到了排序算法,中间的算法和思想比较重要,这边我选择了5种常用排序算法并用Java进行了实现.自己写一个模板已防以后面试用到.大家可以看过算法之后,自己去实现一下. 1.冒泡排序:大数向 ...

  5. 排序算法----基数排序(RadixSort(L,max))单链表版本

    转载http://blog.csdn.net/Shayabean_/article/details/44885917博客 先说说基数排序的思想: 基数排序是非比较型的排序算法,其原理是将整数按位数切割 ...

  6. 排序算法汇总(C/C++实现)

    前言:     本人自接触算法近2年以来,在不断学习中越多地发觉各种算法中的美妙.之所以在这方面过多的投入,主要还是基于自身对高级程序设计的热爱,对数学的沉迷.回想一下,先后也曾参加过ACM大大小小的 ...

  7. 用Java来写常见的排序算法

    随着校招的临近 算法是校招中很重要的一个部分 总结了常见几种排序算法,各种算法的时间复杂度和空间复杂度大家也需要多了解下 package com.huwei.sort; /** * 各种排序算法 * ...

  8. 模板化的七种排序算法,适用于T* vector<T>以及list<T>

    最近在写一些数据结构以及算法相关的代码,比如常用排序算法以及具有启发能力的智能算法.为了能够让写下的代码下次还能够被复用,直接将代码编写成类模板成员函数的方式,之所以没有将这种方式改成更方便的函数模板 ...

  9. 排序算法总结第二弹----冒泡排序---javascript描述

    上篇博文总结了选择排序,这篇来看冒泡排序,接上篇. 冒泡排序思想:若是正再将一组数据升序排序, 第一趟:比较相邻的数据,当左侧值大于右侧值将他们进行交换,将较小值向前浮动,大值向后冒泡,直至比较到最后 ...

  10. 排序算法总结------选择排序 ---javascript描述

    每当面试时避不可少谈论的话题是排序算法,上次面试时被问到写排序算法,然后脑袋一懵不会写,狠狠的被面试官鄙视了一番,问我是不是第一次参加面试,怎么可以连排序算法都不会呢?不过当时确实是第一次去面试,以此 ...

随机推荐

  1. javascript专业八级测试答案整理

    前几天社区的群里森破发了一个这样的链接: http://ourjs.com/detail/52fb82e13bd19c4814000001 做了一遍后突然对人生感到了迷茫,本着不能只有我一个人伤心的原 ...

  2. Socket网络通讯开发总结之:Java 与 C进行Socket通讯(转)

    先交待一下业务应用背景:服务端:移动交费系统:基于C语言的Unix系统客户端:增值服务系统:基于Java的软件系统通迅协议:采用TCP/IP协议,使用TCP以异步方式接入数据传输:基于Socket流的 ...

  3. Oracle Database 11.2.0.4.0 已在 中标麒麟Linux x86-64 NeoKylin Linux Advanced Server 6 上通过认证

    啥都不说了,上截图:

  4. Django——Django中的QuerySet API 与ORM(对象关系映射)

    首先名词解释. ORM: 对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型 ...

  5. Python中函数参数传递问题【转】

    1. Python passes everything the same way, but calling it "by value" or "by reference& ...

  6. redis 大内存主从问题解决

    redis 内存太大使用太大会导致同步陷入循环,每次rdb还没同步完成,新的同步又起,解决办法: redis-cli config set client-output-buffer-limit &qu ...

  7. stm32 IDR寄存器软件仿真的BUG

    /* * 函数名:Key_GPIO_Config * 描述 :配置按键用到的I/O口 * 输入 :无 * 输出 :无 */ void Key_GPIO_Config(void) { GPIO_Init ...

  8. php的pear包管理

    1.安装:  $ sudo wget http://pear.php.net/go-pear.phar  $ sudo php go-pear.har 2.查看pear下安装的包:  $ pear l ...

  9. NIO之直接缓冲区与非直接缓冲区

    直接缓冲区与非直接缓冲区的概念 一.非直接缓冲区 1)创建方式 通过 static ByteBuffer allocate(int capacity) 创建的缓冲区,在JVM中内存中创建,在每次调用基 ...

  10. Arthas安装问题

    1. 下载安装 方式一: 安装Arthas: curl -L https://alibaba.github.io/arthas/install.sh | sh 启动Arthas: ./as.sh 报t ...