五种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) 快速排序 ...
随机推荐
- [leetcode712]204. Count Primes寻找范围内的素数
厄拉多塞筛选法,就是哈希表记录素数的倍数 public int countPrimes(int n) { /* 牛逼哄哄的厄拉多塞筛选法 就是从2开始,每找到一个素数,就把n以内的这个数的倍数排除 记 ...
- String Boot有哪些优点
a.减少开发,测试时间和努力. b.使用 JavaConfig 有助于避免使用 XML.c.避免大量的 Maven 导入和各种版本冲突. d.通过提供默认值快速开始开发.没有单独的 Web 服务器需要 ...
- 改进你的c#代码的5个技巧(二)
在本文中,我将向你展示c#编程的5个最佳实践.我从日常编程经验中学到了这些实践.我在release模式下测试了所有的代码,并在开发环境稳定后进行了截屏.我想你会喜欢这些建议的. 在使用数据类型之前选择 ...
- 分享一个的c++写的,模仿awk的框架类CAwkDoc
这是我好多年前,模仿awk写的. awk大家都比较熟悉,使用awk处理文件,读取文件,分割字段这些工作awk自己帮你实现了. 程序员只要编写业务逻辑代码,并且awk还提供了很多常用的字符串操作函数,可 ...
- 项目中处理数据常用Excel公式
="'"&A1&"'," 需求:是大佬给了excel,里面是700多个单号,要我从生产的数据库中查询出每个单号对应的类型,这时需要查数据库,我决 ...
- CentOS 6安装Gitlab
1. 保证CentOS 6能连接网络 . 2.安装依赖: sudo yum install -y curl policycoreutils-python openssh-server cronie s ...
- 【Linux】kali 安装 python3 和 pip3(亲测有效)
[Linux]kali 安装 python3 和 pip3 引言: 在使用kali的时候,经常会用到各种工具以及脚本,而大多数脚本都是以python编写的,但是烦就烦在python有2个版本,有些 ...
- SpringMVC文件的上传与下载实现
单文件上传 首先创建项目,开发工具是IDEA,选择Spring项目,勾选上Spring和SpringMVC. 然后命名,最后完成. 默认生成配置文件在web/WEB-INF下. 首先导入需要的jar包 ...
- selenium爬虫 | 爬取疫情实时动态(二)
'''@author:Billie更新说明:1-28 17:00 项目开始着手,spider方法抓取到第一条疫情数据,save_data_csv方法将疫情数据保存至csv文件1-29 13:12 目标 ...
- [APUE] 文件 I/O
文件操作相关 API:open, read, write, lseek, close. 多进程共享文件的相关 API:dup, dup2, fcntl, sync, fsync, ioctl. 文件操 ...