五种C语言非数值计算的常用经典排序算法
摘要:排序是计算机的一种操作方法,其目的是将一组“无序”的记录序列调整为“有序”的记录序列,主要分为内部排序和外部排序。
排序
排序是计算机的一种操作方法,其目的是将一组“无序”的记录序列调整为“有序”的记录序列,主要分为内部排序和外部排序。
(1)冒泡排序(起泡排序)
冒泡排序(Bubble Sort),其基本思路是,对于一组要排序的元素列,依次比较相邻的两个数,将比较小的数放在前面,比较大的数放在后面,如此继续,直到比较到最后的两个数,将小数放在前面,大数放在后面,重复步骤,直至全部排序完成。
优点:稳定;
缺点:慢,每次只能移动相邻两个数据。
假设要对含有n个数的序列进行升序排列,冒泡排序算法步骤是:
①从存放序列的数组中的第一个元素开始到最后一个元素,依次对相邻两数进行比较,若前者大后者小,则交换两数的位置;
②第①趟结束后,最大数就存放到数组的最后一个元素里了,然后从第一个元素开始到倒数第二个元素,依次对相邻两数进行比较,若前者大后者小,则交换两数的位置;
③重复步骤①n-1趟,每趟比前一趟少比较一次,即可完成所求。
1、任意读入10个整数,将其用冒泡法按升序排列后输出。
#define n 10 void main()
{
int a[n],i,j,t;
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(j=1;j<=n-1;j++) /*n个数处理n-1趟*/
for(i=0;i<=n-1-j;i++) /*每趟比前一趟少比较一次*/
if(a[i]>a[i+1])
{
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
for(i=0;i<n;i++)
printf("%d\n",a[i]);
}
2、传统方法:
#include <stdio.h> void main()
{
int a[11],i,j,t;
printf("Input 10 numbers:\n");
for(i=1;i<11;i++)
{
scanf("%d",&a[i]);
}
printf("\n");
for(j=1;j<=9;j++)
for(i=1;i<=10-j;i++)
if(a[i]>a[i+1])
{
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
printf("The sorted numbers:\n");
for(i=1;i<11;i++)
printf("%d ",a[i]);
}
(2)选择法排序
选择排序法是每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。基于此思想的算法主要有简单选择排序、树型选择排序和堆排序。
优点:移动数据的次数已知(n-1次);
缺点:比较次数多,不稳定。
选择法排序是相对好理解的排序算法。假设要对含有n个数的序列进行升序排列,算法步骤是:
①从数组存放的n个数中找出最小数的下标(算法见下面的“求最值”),然后将最小数与第1个数交换位置;
②除第1个数以外,再从其余n-1个数中找出最小数(即n个数中的次小数)的下标,将此数与第2个数交换位置;
③重复步骤①n-1趟,即可完成所求。
1、任意读入10个整数,将其用选择法按升序排列后输出。
#include <stdio.h>
#define n 10 void main()
{
int a[n],i,j,k,t;
for(i=0;i<n;i++) scanf("%d",&a[i]);
for(i=0;i<n-1;i++) /*处理n-1趟*/
{
k = i;
/*总是假设此趟处理的第一个(即全部数的第i个)数最小,k记录其下标*/
for(j=i+1;j<n;j++)
if(a[j] < a[k])
k = j;
if (k != i)
{
t = a[i];
a[i] = a[k];
a[k] = t;
}
}
for(i=0;i<n;i++)
printf("%d\n",a[i]);
}
2、传统方法:
#include <stdio.h> void main()
{ int a[11],i,j,k,x;
printf("Input 10 numbers:\n");
for(i=1;i<=10;i++)
scanf("%d",&a[i]);
printf("\n");
for(i=1;i<=10;i++)
{ k=i;
for(j=i+1;j<=10;j++)
if(a[j]<a[k]) k=j;
if(i!=k)
{
x=a[i];
a[i]=a[k];
a[k]=x;
}
}
printf("The sorted numbers:\n");
for(i=1;i<=10;i++)
printf("%d ",a[i]);
}
函数法:
#include <stdio.h> void sort(int array[],int n)
{ int i,j,k,t;
for(i=0;i<n-1;i++)
{ k=i;
for(j=i+1;j<n;j++)
if(array[j]<array[k])
k=j;
if(k!=i)
{ t=array[i];
array[i]=array[k];
array[k]=t;
}
}
} main()
{ int a[10],i;
for(i=0;i<10;i++)
scanf("%d",&a[i]);
sort(a,10);/*数组名作函数参数*/
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("\n");
}
(3)插入法排序
优点:稳定,快;
缺点:比较次数不一定,比较次数越多,插入点后的数据移动越多,特别是当数据总量庞大的时候,但用链表可以解决这个问题。
要想很好地掌握此算法,先请了解“有序序列的插入算法”,就是将某数据插入到一个有序序列后,该序列仍然有序。插入算法参见下面的“数组元素的插入”。
1、将任意读入的整数x插入一升序数列后,数列仍按升序排列。
#include <stdio.h>
#define n 10 void main()
{
int a[n]={-1,3,6,9,13,22,27,32,49},x,j,k; /*注意留一个空间给待插数*/
scanf("%d",&x);
if(x>a[n-2]) a[n-1]=x ; /*比最后一个数还大就往最后一个元素中存放*/
else /*查找待插位置*/
{j=0;
while( j<=n-2 && x>a[j]) j++;
/*从最后一个数开始直到待插位置上的数依次后移一位*/
for(k=n-2; k>=j; k- -)
a[k+1]=a[k];
a[j]=x; /*插入待插数*/
}
for(j=0;j<=n-1;j++) printf("%d ",a[j]);
}
插入法排序的要领就是每读入一个数立即插入到最终存放的数组中,每次插入都使得该数组有序。
2、任意读入10个整数,将其用插入法按降序排列后输出。
#include <stdio.h> #define n 10
main()
{int a[n],i,j,k,x;
scanf("%d",&a[0]); /*读入第一个数,直接存到a[0]中*/
for(j=1;j<n;j++) /*将第2至第10个数一一有序插入到数组a中*/
{scanf("%d",&x);
if(x<a[j-1]) a[j]=x;
/*比原数列最后一个数还小就往最后一个元素之后存放新读的数*/
else /*以下查找待插位置*/
{i=0;
while(x<a[i]&&i<=j-1) i++;
/*以下for循环从原最后一个数开始直到待插位置上的数依次后移一位*/
for(k=j-1;k>=i;k--) a[k+1]=a[k];
a[i]=x; /*插入待插数*/
}
}
for(i=0;i<n;i++)
printf("%d\n",a[i]);
}
(4)归并排序
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并,即将两个都升序(或降序)排列的数据序列合并成一个仍按原序排列的序列。
1、有一个含有6个数据的升序序列和一个含有4个数据的升序序列,将二者合并成一个含有10个数据的升序序列。
#include <stdio.h>
#define m 6
#define n 4 void main()
{
int a[m]={-3,6,19,26,68,100} ,b[n]={8,10,12,22};
int i,j,k,c[m+n];
i=j=k=0;
while(i<m && j<n) /*将a、b数组中的较小数依次存放到c数组中*/
{if(a[i]<b[j]){c[k]=a[i]; i++;}
else {c[k]=b[j]; j++;}
k++; }
while(i>=m && j<n) /*若a中数据全部存放完毕,将b中余下的数全部存放到c中*/
{c[k]=b[j]; k++; j++;}
while(j>=n && i<m) /*若b中数据全部存放完毕,将a中余下的数全部存放到c中*/
{c[k]=a[i]; k++; i++;}
for(i=0;i<m+n;i++) printf("%d ",c[i]);
}
(5)字符数组:(逆序排列)如:<ABCDE-EDCBA>
1、把输入的字符串逆序排列,如输入ABCDE,输出为EDCBA
#include <stdio.h>
#include<string.h> void main()
{ char c,str[80];
int i,j;
printf("Enter a string:\n");
scanf(“%s”,str); /* 也可以gets(str);puts(str); */
for(i=0,j=strlen(str)-1;i<j;i++,j--)
{
c=str[i];
str[i]=str[j];
str[j]=c;
}
printf("\nReversed string:\n%s\n",str);
}
本文分享自华为云社区《C语言非数值计算常用经典算法之排序》,原文作者:Jack20。
五种C语言非数值计算的常用经典排序算法的更多相关文章
- Jerry 2017年的五一小长假:8种经典排序算法的ABAP实现
2017年4月29日~5月1日,国际劳动节, 三天的小长假. 在国内,小长假往往是这样的: 然而我当时在戏称为"德村"(德国农村)的Walldorf出差并且住在Wiesloch, ...
- 【最全】经典排序算法(C语言)
算法复杂度比较: 算法分类 一.直接插入排序 一个插入排序是另一种简单排序,它的思路是:每次从未排好的序列中选出第一个元素插入到已排好的序列中. 它的算法步骤可以大致归纳如下: 从未排好的序列中拿出首 ...
- 数据结构中常用的排序算法 && 时间复杂度 && 空间复杂度
第一部分:数据结构中常用的排序算法 数据结构中的排序算法一般包括冒泡排序.选择排序.插入排序.归并排序和 快速排序, 当然还有很多其他的排序方式,这里主要介绍这五种排序方式. 排序是数据结构中的主要内 ...
- java SE 常用的排序算法
java程序员会用到的经典排序算法实现 常用的排序算法(以下代码包含的)有以下五类: A.插入排序(直接插入排序.希尔排序) B.交换排序(冒泡排序.快速排序) C.选择排序(直接选择排序.堆排序) ...
- JavaScript实现常用的排序算法
▓▓▓▓▓▓ 大致介绍 由于最近要考试复习,所以学习js的时间少了 -_-||,考试完还会继续的努力学习,这次用原生的JavaScript实现以前学习的常用的排序算法,有冒泡排序.快速排序.直接插入排 ...
- 七种经典排序算法及Java实现
排序算法稳定性表示两个值相同的元素在排序前后是否有位置变化.如果前后位置变化,则排序算法是不稳定的,否则是稳定的.稳定性的定义符合常理,两个值相同的元素无需再次交换位置,交换位置是做了一次无用功. 下 ...
- 七种常见经典排序算法总结(C++实现)
排序算法是非常常见也非常基础的算法,以至于大部分情况下它们都被集成到了语言的辅助库中.排序算法虽然已经可以很方便的使用,但是理解排序算法可以帮助我们找到解题的方向. 1. 冒泡排序 (Bubble S ...
- 常用Java排序算法
常用Java排序算法 冒泡排序 .选择排序.快速排序 package com.javaee.corejava; public class DataSort { public DataSort() { ...
- C#中常用的排序算法的时间复杂度和空间复杂度
常用的排序算法的时间复杂度和空间复杂度 常用的排序算法的时间复杂度和空间复杂度 排序法 最差时间分析 平均时间复杂度 稳定度 空间复杂度 冒泡排序 O(n2) O(n2) 稳定 O(1) 快速排序 ...
随机推荐
- node2vec实现源码详解
一.按照程序执行的顺序,第一步是walker.py中的preprocess_transition_probs()函数 这个函数的作用是生成两个采样预备数据,alias_nodes,alias_edge ...
- Mac电脑 Android Studio连接小米手机
1.设置>关于本机>点击5下MIUI版本>激活开发者模式 2.设置>更多设置>开发者选项>开启开发者选项>开启USB调试>开启USB安装>开启显示 ...
- Linux 时间同步 04 ntp时间同步
Linux 时间同步 04 ntp时间同步 目录 Linux 时间同步 04 ntp时间同步 安装ntp 配置与外部时间服务器进行时间同步的客户端主机 配置其他客户端与以上客户端主机时间同步 验证查看 ...
- reactor模式:主从式reactor
前面两篇文章提到 reactor模式:单线程的reactor模式 reactor模式:多线程的reactor模式 NIO的server模式只有5个阶段,但是,NIO的selectionkey里确实有个 ...
- Docker学习(二)- Docker 安装 Jenkins
一.拉取镜像 我这里安装的版本是2.222.3-centos,可以去这里获取你需要的版本: https://hub.docker.com/_/jenkins?tab=tags docker pull ...
- vue项目中使用日期获取今日,昨日,上周,下周,上个月,下个月的数据
今日公司项目接口要求获取动态的上周数据,经过不断的寻找,找到此方法. 该方法使用的是Moment.js JavaScript日期处理类库 一:安装依赖 npm install moment --sav ...
- ElasticSearch教程——filter与query对比(转学习使用)
一.数据准备 PUT /company/employee/2 { "address": { "country": "china", &quo ...
- MMDetection 快速开始,训练自定义数据集
本文将快速引导使用 MMDetection ,记录了实践中需注意的一些问题. 环境准备 基础环境 Nvidia 显卡的主机 Ubuntu 18.04 系统安装,可见 制作 USB 启动盘,及系统安装 ...
- 【JDBC核心】commons-dbutils
commons-dbutils 简介 commons-dbutils 是 Apache 组织提供的一个开源 JDBC 工具类库,它是对 JDBC 的简单封装,学习成本极低,并且使用 commons-d ...
- 当Django设置DEBUG为False时,发现admin和html的静态资源文件加载失败的解决办法
当Django设置DEBUG为False时,发现admin和html的静态资源文件加载失败,折腾一段时间终于找到解决办法: 1.先在setting文件增加BASE_DIR(项目的路径) BASE_DI ...