c语言sort函数从大到小排序_数据结构与算法(二)——十大排序算法

52725ec237c9db894a46e3078030c47a.png

前言

秋招已经开启一个月了,九月份和十月份是我们秋招找工作的黄金时期。但是大多数的企业都会在笔试或者面试中会考察我们数据结构的知识点,有的会直接考查数据结构的代码实现,比如说树的三种深度优先遍历代码递归以及迭代方式的实现。其次就是考察最多的就是几种排序和常用的查找方法,需要我们熟练掌握。还有的就是会通过一个实际问题来对相关的算法进行考察,比如说动态规划、穷举法、贪心算法等。前一篇文章给大家介绍了数据结构中帮助大家理解代码的执行过程和相应算法的工具。本文给大家介绍数据结构中最为重要也是面试中经常考察的算法之一——排序算法的总结。

十大排序算法实现

在数据结构与算法中,我们会学到十大算法,他们分别是冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序。我们在任何时候,都应该要写出相关的代码,只有这样,我们才能够在写其他算法中更好的应用。由于该算法比较基础,也是比较重要的,接下来,我们通过C语言、java和python三种流行语言将其算法进行实现。接下来给大家介绍第一种排序——冒泡排序的实现。

1、冒泡排序

冒泡排序的原理在于要么元素上浮,从右(大)往左(小)依次确认,相邻元素间,如果右小于左,则交换,每次确认一位最小数。要么元素下沉,从左(小)往右(大)依次确认,相邻元素间,如果左大于右,则交换,每次确认一位最大数。我们用动图解释如下:

0c41c73d0ad0c729507da714f797afda.gif

接下来我们分别用C语言、java和python3三种语言将其实现:

1、我们用C语言将其实现,代码如下:

#include

排序效果如下图所示:

870cfe211d780d45d40caa2adf857c40.png

2、我们用java语言将其实现,代码如下:

package 

排序效果如下图所示:

989ea194c1097a89b52656a3ad5d6004.png

3、我们用python语言将其实现,代码如下:

def 

排序效果如下图所示:

657415b18d42a79837739a3058294360.png

2、选择排序

选择排序的原理在于要么拿未确认的最左位元素,依次和右边元素比较,如果右边元素更小,则交换。要么拿未确认的最右位元素,依次和左边元素比较,如果左边元素更大,则交换。我们用动态图解释如下:

0c111ac57c743bd7ae80fef6ebcb0872.gif

接下来我们分别用C语言、java和python3三种语言将其实现:

1、我们用C语言将其实现,代码如下:

#include

效果图如图所示:

de5606eb65007ac7f2864fe6ec3b312d.png

2、我们用java语言将其实现,代码如下:

package 

排序效果如下图所示:

8ed6043731caedbde3dab0f073eded21.png

3、我们用python语言将其实现,代码如下:

def 

排序效果如下图所示:

57c6f275347a483cd288fed61ce1864a.png

3、插入排序

插入排序的原理在于:将某一元素插入已经排序好的数组中,元素位于数组右方,则元素依次与左方比较,找出合适位置,被比较元素后移一位,该元素前置,要么元素位于数组左方,则元素依次与右方比较,找出合适位置,被比较元素前移一位,该元素后置。我们用动图解释如下:

a238e01134f21b3c6f32ef36c190531b.gif

接下来我们分别用C语言、java和python3三种语言将其实现:

1、我们用C语言将其实现,代码如下:

#include 

排序效果如下图所示:

cb911bc333263384e58df64b5cd17f9a.png

2、我们用java语言将其实现,代码如下:

package 

排序效果如下图所示:

267924e4816c7585d8564c316de75f98.png

3、我们用python语言将其实现,代码如下:

def 

排序效果如下图所示:

1d6c2341e0504d94e9522fb4f8abafdc.png

4、希尔排序

希尔排序的原理在于按照一定间隔(记d)执行插入排序,要么元素位于数组右方,记索引为x,则元素依次与左方x-d的元素比较,找出合适位置,被比较元素后移一位,该元素前置。要么元素位于数组左方,记索引为x,则元素依次与右方x+d的元素比较,找出合适位置,被比较元素前移一位,该元素后置。我们用动图解释如下:

ada48c357f47d27747f0ee5af95dad7b.gif

接下来我们分别用C语言、java和python3三种语言将其实现:

1、我们用C语言将其实现,代码如下:

#include 

排序效果如下图所示:

ce51331919e6141eb71fc6ba563696dd.png

2、我们用java语言将其实现,代码如下:

package 

排序效果如下图所示:

3b8e848c3da8438fe6ebc9b25429fe1c.png

3、我们用python语言将其实现,代码如下:

def 

排序效果如下图所示:

1d7a42798bd6448e1fb4f7a492ed17ad.png

5、归并排序

归并排序的原理在于采用分而治之的思想:将数组等分为若干子数组,对每个子数组排序,然后再合并有序的子数组。我们用动图解释如下:

bfb230a201b6264167f68e0b2b3bf0c8.gif

接下来我们分别用C语言、java和python3三种语言将其实现:

1、这里需要注意的是:归并排序分为递归和迭代两种方法实现,我们用C语言将其实现,代码如下:

①、迭代版实现:

#include 

排序效果如下图所示:

4263a6d832403c3c9591b85ef061efe4.png

②、递归版实现如下:

#include

排序效果如下图所示:

73a9c28a73cd57c393412913534c90ec.png

2、我们用java语言将其实现,代码如下:

package 

排序效果如下图所示:

e9a5eba806d205569a42ccd2b3230173.png

3、我们用python语言将其实现,代码如下:

def 

排序效果如下图所示:

60b6ea1d9e684231664957862f0a0961.png

6、快速排序

快速排序的原理在于采用分而治之的思想:

  • 第一步、选取基准值,小于基准值的在左侧作为子数组,大于基准值的在右侧作为子数组,
  • 第二步、再对两个子数组重复上一步操作
  • 第三步、合并所有子数组

我们用动图解释如下:

15774b2ab04111c0274231e8329e00d6.gif

接下来我们分别用C语言、java和python3三种语言将其实现:

1、我们用C语言将其实现,代码如下:

#include 

排序效果如下图所示:

6398e6576537f5197141f40b5ffed902.png

2、我们用java语言将其实现,代码如下:

package 

排序效果如下图所示:

2c5c06f909a93a7b8dc2370a42804e36.png

3、我们用python语言将其实现,代码如下:

def 

1a442c9c88d77655b84cb10fe1053fa0.png

7、堆排序

堆排序的原理在于将待排序序列构造成一个大顶堆(arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] ),此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。我们用动图解释如下:

1d7520c0805a6a6831ee31eeaf2c658d.gif

接下来我们分别用C语言、java和python3三种语言将其实现:

1、我们用C语言将其实现,代码如下:

#include 

排序效果如下图所示:

79927ff40d80b4df73534bed473ea6f2.png

2、我们用java语言将其实现,代码如下:

package 

排序效果如下图所示:

a04796a916a4906805a546ded3591a24.png

3、我们用python语言将其实现,代码如下:

import 

排序效果如下图所示:

df0d2af1ac18b73fb72174ebc8bdbd23.png

8、计数排序

计数排序的原理在于利用桶的概念:一个桶存单一的键值。根据待排序数组A创建计数数组B,B首位代表A最小值,B末位代表A最大值,遍历A,在B中记录所有元素出现次数。遍历B,根据索引与最小值距离,以及出现次数排序。我们用动图解释如下:

dc5c3f7e8a312aa45c73afd7e4bb1419.gif

接下来我们分别用C语言、java和python3三种语言将其实现:

1、我们用C语言将其实现,代码如下:

#include 

排序效果如下图所示:

ee0d9c90ed39c989fd8d3f63b880f359.png

2、我们用java语言将其实现,代码如下:

package 

排序效果如下图所示:

5acb60139d04b7766b20be223f2242eb.png

3、我们用python语言将其实现,代码如下:

def 

排序效果如下图所示:

fb63f919db958246604744a58a9b990f.png

9、桶排序

桶排序的原理利用桶的概念:一个桶存一定范围的元素。设置一个定量的数组当作空桶,遍历输入数据,并且把数据一个一个放到对应的桶里去,对每个不是空的桶进行排序,从不是空的桶里把排好序的数据拼接起来。我们用动图解释如下:

62ec35e41df7f0ea3f00d2d57e97af98.gif

接下来我们分别用C语言、java和python3三种语言将其实现:

1、我们用C语言将其实现,代码如下:

#include 

排序效果如下图所示:

aa46daff805581781074e93a1a677433.png

2、我们用java语言将其实现,代码如下:

package 

排序效果如下图所示:

a8600bc3480ebb555c7802cd30306b7f.png

3、我们用python语言将其实现,代码如下:

def 

排序效果如下图所示:

7eb671705696d650861c40fbe1ef8c09.png

10、基数排序

基数排序的原理在于利用桶的概念:根据键值的每位数字来分配桶。取得数组中的最大数,并取得位数;arr为原始数组,从最低位开始取每个位组成radix数组;对radix进行计数排序(利用计数排序适用于小范围数的特点);我们用动图解释如下:

0642fa4ac37d27a8c3ea82ec44194e18.gif

接下来我们分别用C语言、java和python3三种语言将其实现:

1、我们用C语言将其实现,代码如下:

#include

排序效果如下图所示:

8f42df03c53e5ac559442309d1e9c10a.png

2、我们用java语言将其实现,代码如下:

package 

排序效果如下图所示:

706c8befebda753b51549e3e49d594d6.png

3、我们用python语言将其实现,代码如下:

def 

排序效果如下图所示:

7774f15fa1f5962e36893d541be149ae.png

以上就是这十大核心排序算法的原理,为了方便大家理解,每种算法都配有动态图帮助大家更好的理解。每种算法都给出了当前最主流的三种语言(C、java、python),希望大家至少要熟练掌握一种语言,不仅仅要在编译器上写出来,也得需要在A4白纸上写出正确的代码,这是作为一个秋招的学生应具备的基本的专业素养。最后,在给大家分析每种算法的时间和空间复杂度以及相应的排序过程的稳定性。

十大排序算法复杂度分析

我们可以通过一张表来概括其各大算法的时间复杂度以及相应的空间复杂度和在排序过程中是否稳定。在介绍之前,我们首先给大家普及时间复杂度、空间复杂度和稳定性的相关知识。通常,对于一个给定的算法,我们要做 两项分析。第一是从数学上证明算法的正确性,这一步主要用到形式化证明的方法及相关推理模式,如循环不变式、数学归纳法等。而在证明算法是正确的基础上,第二部就是分析算法的时间复杂度。算法的时间复杂度反映了程序执行时间随输入规模增长而增长的量级,在很大程度上能很好反映出算法的优劣与否。因此,作为程序员,掌握基本的算法时间复杂度分析方法是很有必要的。

算法执行时间需通过依据该算法编制的程序在计算机上运行时所消耗的时间来度量。一个算法的空间复杂度(Space Complexity)S(n)定义为该算法所耗费的存储空间,它也是问题规模n的函数。渐近空间复杂度也常常简称为空间复杂度。

空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度。一个算法在计算机存储器上所占用的存储空间,包括存储算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面。算法的输入输出数据所占用的存储空间是由要解决的问题决定的,是通过参数表由调用函数传递而来的,它不随本算法的不同而改变。存储算法本身所占用的存储空间与算法书写的长短成正比,要压缩这方面的存储空间,就必须编写出较短的算法。算法在运行过程中临时占用的存储空间随算法的不同而异,有的算法只需要占用少量的临时工作单元,而且不随问题规模的大小而改变,我们称这种算法是“就地"进行的,是节省存储的算法,如这一节介绍过的几个算法都是如此;有的算法需要占用的临时工作单元数与解决问题的规模n有关,它随着n的增大而增大,当n较大时,将占用较多的存储单元。

排序算法的稳定性通俗地讲就是能保证排序前两个相等的数据其在序列中的先后位置顺序与排序后它们两个先后位置顺序相同。即:如,如果A i == A j,Ai 原来在 Aj 位置前,排序后 Ai 仍然是在 Aj 位置前。如果排序算法是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所利用。基数排序就是这样,先按低位排序,逐次按高位排序,那么,低位相同的数据元素其先后位置顺序即使在高位也相同时是不会改变的。学习排序原理时,可能编的程序里面要排序的元素都是简单类型,实际上真正应用时,可能是对一个复杂类型(自定义类型)的数组排序,而排序的键值仅仅只是这个元素中的一个属性,对于一个简单类型,数字值就是其全部意义,即使交换了也看不出什么不同。但是,对于复杂类型,交换的话可能就会使原本不应该交换的元素交换了。比如:一个“学生”数组,欲按照年龄排序,“学生”这个对象不仅含有“年龄”,还有其它很多属性。假使原数组是把学号作为主键由小到大进行的数据整理。而稳定的排序会保证比较时,如果两个学生年龄相同,一定不会交换。也就意味着尽管是对“年龄”进行了排序,但是学号顺序仍然是由小到大的要求。如果排序算法稳定,对基于比较的排序算法而言,元素交换的次数可能相对会少一些。

接下来,我们用一张表来总结这十大算法的相应的复杂度和是否稳定。

a998dc35d9f18d68d67beceacaa7763c.png

总结

本文介绍了十大排序算法的原理、用动态图描述算法的过程。分别用C语言程序设计、java程序设计以及python实现。最后给大家介绍了算法的空间、时间复杂度以及在排序过程中是否稳定,通过一张图来总结了十大算法所占的空间和时间复杂度以及相应的稳定性。这是我们学其他计算机相关专业的大前提。数据结构理解的好坏直接决定我们代码的优劣程度,因此需要我们对数据结构与算法有着深层次的理解。下一篇文章将会给大家介绍数据结构中最为重要的查找算法。最后希望大家学有所成,未来可期,同时也希望自己能够早日找到心仪的工作!!!!!

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值