常规函数均采用如下形式(字符型排序):

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*交换字符串两项*/
void exchange(char *in, int i1, int i2)
{char ch = (char)in[i1];in[i1] = in[i2];in[i2] = ch;
}
/*字符串长度*/
int length(char *in)
{int i=0;while(in[i] != '\0')i++;return i;
}
/*输出字符串*/
void showString(char *str)
{int N = length(str);int i=0;while(i<N){printf("%c ",str[i]);i++;}printf("\n");
}

选择排序

找到数组中的最小元素,将它与数组的第一个元素交换位置。再从剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。不断进行这样的操作,直到将整个数组排序。

/*选择排序*/
void selectSort(char *in)
{int i, j, min;int N = length(in);for(i=0;i<N-1;i++){min = i;for(j=i+1;j<N;j++){if(in[j]<in[min]) min = j; }exchange(in,i,min);showString(in);}
}

选择排序需要 ~N^2/2 次比较和 ~N 次交换,它的运行时间与输入无关,这个特点使得它对一个已经排序的数组也需要这么多的比较和交换操作。

插入排序

插入排序从左到右进行,每次都将当前元素插入到左部已经排序的数组中,使得插入之后左部数组依然有序。

/*插入排序*/
void insertSort(char *in)
{int i, j;int N = length(in);for(i=1;i<N;i++){for(j=i; j>0 && in[j]<in[j-1]; j--){exchange(in,j,j-1);showString(in);}}
}

插入排序的复杂度取决于数组的初始顺序,如果数组已经部分有序了,那么插入排序会很快。
平均情况下插入排序需要 ~N^2/4 比较以及 ~N^2/4 次交换;
最坏的情况下需要 ~N^2/2 比较以及 ~N^2/2 次交换,最坏的情况是数组是逆序的;
最好的情况下需要 N-1 次比较和 0 次交换,最好的情况就是数组已经有序了。

插入排序对于部分有序数组和小规模数组特别高效。

希尔排序
对于大规模的数组,插入排序很慢,因为它只能交换相邻的元素,如果要把元素从一端移到另一端,就需要很多次操作。
希尔排序的出现就是为了改进插入排序的这种局限性,它通过交换不相邻的元素,使得元素更快的移到正确的位置上。

希尔排序使用插入排序对间隔 h 的序列进行排序,如果 h 很大,那么元素就能很快的移到很远的地方。通过不断减小 h,最后令 h=1,就可以使得整个数组是有序的。

/*希尔排序*/
void shellSort(char *in)
{int i, j;int N = length(in);int h = 1;while(h < N / 3) {h = 3 * h + 1; // 1, 4, 13, 40, ...}while (h >= 1) {for (i = h; i < N; i++) {for (j = i; j >= h && in[j]<in[j - h]; j -= h) {exchange(in, j, j - h);printf("(%d,%d)%d, ",i,j,h);showString(in);}}h = h / 3;}
}

希尔排序的运行时间达不到平方级别,使用递增序列 1, 4, 13, 40, ... 的希尔排序所需要的比较次数不会超过 N 的若干倍乘于递增序列的长度。后面介绍的高级排序算法只会比希尔排序快两倍左右。

全部代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>/*交换字符串两项*/
void exchange(char *in, int i1, int i2)
{char ch = (char)in[i1];in[i1] = in[i2];in[i2] = ch;
}
/*字符串长度*/
int length(char *in)
{int i=0;while(in[i] != '\0')i++;return i;
}
/*输出字符串*/
void showString(char *str)
{int N = length(str);int i=0;while(i<N){printf("%c ",str[i]);i++;}printf("\n");
}
/*选择排序*/
void selectSort(char *in)
{int i, j, min;int N = length(in);for(i=0;i<N-1;i++){min = i;for(j=i+1;j<N;j++){if(in[j]<in[min]) min = j; }exchange(in,i,min);showString(in);}
}/*插入排序*/
void insertSort(char *in)
{int i, j;int N = length(in);for(i=1;i<N;i++){for(j=i; j>0 && in[j]<in[j-1]; j--){exchange(in,j,j-1);showString(in);}}
}/*希尔排序*/
void shellSort(char *in)
{int i, j;int N = length(in);int h = 1;while(h < N / 3) {h = 3 * h + 1; // 1, 4, 13, 40, ...}while (h >= 1) {for (i = h; i < N; i++) {for (j = i; j >= h && in[j]<in[j - h]; j -= h) {exchange(in, j, j - h);showString(in);}}h = h / 3;}
}/*main函数*/
int main(int argc, char**argv)
{char str[] = "hgfedbca";showString(str);shellSort(str);showString(str);return 1;
}

更多内容: https://github.com/CyC2018/Interview-Notebook

本文只是对Java代码进行了C语言重写,如有侵权请联系删除!

排序算法:选择排序、插入排序、希尔排序相关推荐

  1. 【Java】5大排序算法总结(插入排序+希尔排序+选择排序+堆排序+冒泡排序)

    快速导航: 1. 稳定性 2 . 插入排序 3. 希尔排序 4. 选择排序 5. 堆排序 6 冒泡排序 1. 稳定性 两个相等的数据,如果经过排序后,排序算法能保证其相对位置不发生变化,则我们称该算法 ...

  2. [ 数据结构 -- 手撕排序算法第三篇 ] 希尔排序

    手撕排序算法系列之:希尔排序. 从本篇文章开始,我会介绍并分析常见的几种排序,大致包括插入排序,冒泡排序,希尔排序,选择排序,堆排序,快速排序,归并排序等. 大家可以点击此链接阅读其他排序算法:排序算 ...

  3. 排序上---(排序概念,常见排序算法,直接插入,希尔排序,直接选择排序,堆排序)

    排序的概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作. 稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对 ...

  4. shell排序_Python排序算法(五)希尔排序

    一. 核心思想 希尔排序(shell_Sort),也称递减增量排序算法,是插入排序的一种更高效的改进版本.基本思想:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录& ...

  5. 希尔排序的详细过程_算法系列: 10大常见排序算法(4)希尔排序

    本课程是从少年编程网转载的课程,目标是向中学生详细介绍计算机比赛涉及的编程语言,数据结构和算法.编程学习最好使用计算机,请登陆 www.3dian14.org (免费注册,免费学习). 一句 希尔排序 ...

  6. 【十大经典排序算法】java实现--希尔排序(4)

    希尔排序概述: 先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序. 选择一个增量序列 t1,t2, ...

  7. Python排序算法(二) 快速排序、希尔排序、归并排序

    这篇文章有的排序算法是:快速排序.希尔排序.归并排序. 快速排序 ''' 快速排序 '''def quick_sort(aList, first, last):if first >= last: ...

  8. 希尔排序法。Java实现希尔排序

    前言基础: 1.因为希尔排序法的步长选取不是固定的,不同的步长会对应不同的复杂度,但是综合起来希尔排序法的时间复杂度是在O(nlogn)~O(n2)之间,近似为O(n的1.3次幂).空间复杂度为O(1 ...

  9. C语言——十四种内部排序算法【直接插入排序-冒泡排序-选择排序-插入排序-希尔排序-归并排序-快速排序-堆排序-折半插入排序-二分查找-路插入排序-表插入排序-简单选择排序-直接选择排序-树形选择】

    目录: 一:插入排序 A:直接插入排序 1.定义: 2.算法演示 实例1: 3.基本思想 4.排序流程图 实例1: B:希尔排序 1.定义: 2.算法演示 实例2: C:其他插入排序 a:折半插入排序 ...

  10. 对以下6种常用的内部排序算法进行比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。

    题目要求: (1)对以下6种常用的内部排序算法进行比较:起泡排序.直接插入排序.简单选择排序.快速排序.希尔排序.堆排序. (2)待排序表的表长不小于100:其中的数据要用伪随机数产生程序产生:至少要 ...

最新文章

  1. 在MM32F3273上运行MicroPython,对于性能进行测试
  2. Win7旗舰版安装Oracle_11gR1_database
  3. 损失函数中正则化项L1和L2的理解
  4. Node.js基础知识普及
  5. 为什么你不应该接受有 race 的代码
  6. Android开发面试题之Activity启动模式讲解总结
  7. 万箭齐发!COSCon' 21深圳分会场闪亮登场!
  8. 一文了解Redis持久化
  9. Apple individual program 加入之后的玩法 官方资源
  10. 西南石油大学计算机科学学院教授,张小洪(计算机科学学院)老师 - 西南石油大学 - 院校大全...
  11. java容量_java中常用集合类的容量
  12. python生成器的实现及原理
  13. 8个优质自学网站收藏
  14. VMware Ubuntu虚拟机非正常关机的恢复
  15. 人工智能之路学习计划
  16. SAP idoc功能够强大: 采购订单下达自动触发销售订单创建
  17. android用代码返回桌面
  18. 统计学离散型变量和连续型变量有什么区别?
  19. 有15个数按由大到小顺序存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个元素的值。如果该数不在数组中,则输出“无此数”
  20. 利用pypdf2 安装包 基于 python 制作的PDF 文档合并脚本

热门文章

  1. 实现Runnable接口
  2. Java并发编程-ConcurrentHashMap
  3. leetcode题解189-旋转数组
  4. 网页百度地图api,支持位置偏移
  5. datagrip 导出数据库备份到本地
  6. Spring Cloud学习笔记-009
  7. Android中libs目录下armeabi和armeabi-v7a的区别
  8. IIS7的FTP出错: 451 No mapping for the unicode character exists in the target multi-byte code page
  9. wps表格里面计算机在哪里,“Excel表格软件在电脑上到哪里找?“电脑excle在哪里...
  10. centos6下如何安装mysql服务_CentOS6下安装MySQL数据库服务