插入排序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=;i<n;i++){
temp=*(array+i);
for(j=i;j>&&*(array+j-)>temp;j--){
*(array+j)=*(array+j-);
}
*(array+j)=temp;
}
}

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

  冒泡排序算法的运作如下:
  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
  5. #include<stdio.h>
    #defineSIZE8
    void bublle_sort(int a[],int n){//n为数组a的元素个数
    int i,j,temp;
    for(j=;j<n-;j++)
    for(i=;i<n--j;i++)
    if(a[i]>a[i+]){//数组元素大小按升序排列
    temp=a[i];
    a[i]=a[i+];
    a[i+]=temp;
    }
    }
    int main(){
    int number[SIZE]={,,,,,,,};
    int i;
        bublle_sort(number,SIZE);
    for(i=;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 =; i < n -; i ++) {
min = i; //查找最小值
for( j = i +; 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=,j=numsize-;
int val=a[];//指定参考值val大小
if(numsize>){//确保数组长度至少为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+,numsize--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]; * i + < nLength; i = nChild)
{
// 子结点的位置=2*(父结点位置)+ 1
nChild = * i + ;
// 得到子结点中较大的结点
if ( nChild < nLength- && array[nChild + ] > 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 -)/ ; i >= ; --i)
HeapAdjust(array, i, length);
// 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
for (int i = length - ; i > ; --i)
{
// 把第一个元素和当前的最后一个元素交换,
// 保证当前的最后一个位置的元素都是在现在的这个序列之中最大的
/// Swap(&array[0], &array[i]);
tmp = array[i];
array[i] = array[];
array[] = tmp;
// 不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值
HeapAdjust(array, , 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+, 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 = ; k <= midIndex-startIndex; k++)
{
targetArr[j+k] = sourceArr[startIndex+k];
}
} if(i <= endIndex)
{
for(k = ; 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[]; //此处大小依需求更改
if(startIndex == endIndex)
{
targetArr[startIndex] = sourceArr[startIndex];
}
else
{
midIndex = (startIndex + endIndex)/;
MergeSort(sourceArr, tempArr, startIndex, midIndex);
MergeSort(sourceArr, tempArr, midIndex+, endIndex);
Merge(tempArr, targetArr,startIndex, midIndex, endIndex);
}
} //调用
int _tmain(int argc, _TCHAR* argv[])
{
int a[]={,,,,,,,};
int b[];
MergeSort(a, b, , );
for(int i = ; i < sizeof(a) / sizeof(*a); i++)
cout << b[i] << ' ';
cout << endl;
system("pause");
return ;
}
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/;d >= ;d = d/){
for(i = d; i < n;i++){
temp = a[i];
for(j = i - d;(j >= ) && (a[j] > temp);j = j-d){
a[j + d] = a[j];
}
a[j + d] = temp;
}
}
}

各种排序算法及c语言实现的更多相关文章

  1. 【最全】经典排序算法(C语言)

    算法复杂度比较: 算法分类 一.直接插入排序 一个插入排序是另一种简单排序,它的思路是:每次从未排好的序列中选出第一个元素插入到已排好的序列中. 它的算法步骤可以大致归纳如下: 从未排好的序列中拿出首 ...

  2. 排序算法总结(C语言版)

    排序算法总结(C语言版) 1.    插入排序 1.1     直接插入排序 1.2     Shell排序 2.    交换排序 2.1     冒泡排序 2.2     快速排序 3.    选择 ...

  3. 几种经典排序算法的R语言描述

    1.数据准备 # 测试数组 vector = c(,,,,,,,,,,,,,,) vector ## [] 2.R语言内置排序函数 在R中和排序相关的函数主要有三个:sort(),rank(),ord ...

  4. 【转载】常见十大经典排序算法及C语言实现【附动图图解】

    原文链接:https://www.cnblogs.com/onepixel/p/7674659.html 注意: 原文中的算法实现都是基于JS,本文全部修改为C实现,并且统一排序接口,另外增加了一些描 ...

  5. [answerer的算法课堂]简单描述4种排序算法(C语言实现)

    [answerer的算法课堂]简单描述4种排序算法(C语言实现) 这是我第一次写文章,想要记录自己的学习生活,写得不好请包涵or指导,本来想一口气写好多种,后来发现,写太多的话反而可读性不强,而且,我 ...

  6. 链表插入和删除,判断链表是否为空,求链表长度算法的,链表排序算法演示——C语言描述

    关于数据结构等的学习,以及学习算法的感想感悟,听了郝斌老师的数据结构课程,其中他也提到了学习数据结构的或者算法的一些个人见解,我觉的很好,对我的帮助也是很大,算法本就是令人头疼的问题,因为自己并没有学 ...

  7. 常用七大经典排序算法总结(C语言描述)

    简介 其中排序算法总结如下: 一.交换排序 交换排序的基本思想都为通过比较两个数的大小,当满足某些条件时对它进行交换从而达到排序的目的. 1.冒泡排序 基本思想:比较相邻的两个数,如果前者比后者大,则 ...

  8. 排序算法的C语言实现(上 比较类排序:插入排序、快速排序与归并排序)

    总述:排序是指将元素集合按规定的顺序排列.通常有两种排序方法:升序排列和降序排列.例如,如整数集{6,8,9,5}进行升序排列,结果为{5,6,8,9},对其进行降序排列结果为{9,8,6,5}.虽然 ...

  9. 排序算法的C语言实现(下 线性时间排序:计数排序与基数排序)

    计数排序 计数排序是一种高效的线性排序. 它通过计算一个集合中元素出现的次数来确定集合如何排序.不同于插入排序.快速排序等基于元素比较的排序,计数排序是不需要进行元素比较的,而且它的运行效率要比效率为 ...

  10. [算法] 常见排序算法总结(C语言版)

    常见排序算法总结 本文对比较常用且比较高效的排序算法进行了总结和解析,并贴出了比较精简的实现代码,包括选择排序.插入排序.归并排序.希尔排序.快速排序等.算法性能比较如下图所示: 1 冒泡排序 基本原 ...

随机推荐

  1. [liu yanling]软件测试技巧

    1.添加.修改功能 (1)是否支持tab键 (2)是否支持enter键 (3)不符合要求的地方是否有错误提示 (4)保存后,是否也插入到数据库中 (5)字段唯一的,是否可以重复添加 (6)对编辑页列表 ...

  2. sublime text 3 中 SFTP插件 的 配置

    SFTP 插件.主要功能就是通过 FTP/SFTP 连接远程服务器并获取文件列表,可以选择下载编辑.重命名.删除等等操作,点下载编辑之后,可以打开这个文件进行修改.修改完成之后,保存一下会自动上传到远 ...

  3. 【原】 Spark中Task的提交源码解读

    版权声明:本文为原创文章,未经允许不得转载. 复习内容: Spark中Stage的提交 http://www.cnblogs.com/yourarebest/p/5356769.html Spark中 ...

  4. 【CSS3】Advanced1:Rounded Corners

    1.Border radius The border-radius property can be used to working clockwise from top-left set border ...

  5. oracle sys sysman system 介绍

    Oracle数据库中SYS.SYSTEM.DBSNMP.SYSMAN四用户的区别 SYS用户: SYS,默认密码为CHANGE_ON_INSTALL,当创建一个数据库时,SYS用户将被默认创建并授予D ...

  6. Linux vim的一些命令

    一.vi/vim的多行注释及取消注释 1.多行注释 (1) 进入命令行模式,按ctrl + v进入 visual block模式,然后按j, 或者k选中多行,把需要注释的行标记起来 (2) 按大写字母 ...

  7. A Tour of Go Slicing slices

    ---恢复内容开始--- Slices can be re-sliced, creating a new slice value that points to the same array. The ...

  8. linux下查询域名或IP注册信息的操作记录(whois)

    在运维工作中,有时需要查询某些域名的注册信息(域名的NS,注册用户,注册邮箱等),可以使用whois这个命令.whois命令令用来查找并显示指定帐号(或域名)的用户相关信息,因为它是到Network ...

  9. Codeforces Round #382 (Div. 2)E. Ostap and Tree

    E. Ostap and Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  10. 跟我学SpringMVC目录汇总贴、PDF下载、源码下载

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...