最近看了一句话,说的是在现实生活中,会写字的人不见得会写出好文章,学习编程语言就像是学会了写字,学会了编程语言并不一定能写出好程序。

我觉得就是很有道理,以前读书的时候,基本学完了C#中的语法知识,算是入了个门,但是一到写程序就毫无头绪,做出来的程序就像是小学生日记,仅仅只是用一些简单的api把功能拼凑起来,没有一点逻辑性,毫不美观优雅。

所以我决定慢慢的开始学习算法知识,虽然我数学很烂,逻辑能力差到极点,看这些算法的代码看的我是心态爆炸,真的头皮发麻,只有长期坚持学习,一点一点的慢慢进步了。

快速排序是分治法中的一种常见排序算法,主要运用递归求解。

算法思想是将一个数组分为小于等于基准数的子数组和大于基准数的子数组,然后通过递归调用,不断对这两个子数组进行排序,直到数组元素只有0个或1个元素时,停止递归,再将各个排好序的子数组加起来,最终就得到了排好序的数组。

步骤如下:

1. 选择一个基准值

2. 将数组分为两个子数组:小于基准值的元素和大于基准值的元素

3. 对这两个子数组进行排序

接着对子数组重复以上3步,直到子数组无法分解(子数组只有0个或1个元素时)

可以使用函数递归重复上述过程,在递归函数中必须满足2个条件

1.基线条件——指满足某个条件以后,函数不在调用自身进行递归

2.递归条件——满足递归条件就调用自身函数进行递归

我看的书举例是使用Python代码实现的快速排序,代码如下:

 def quicksort(array):
if len(array) < 2: #基线条件:为空或者只包含一个元素的数组是“有序”的
return array
else:#递归条件
pivot = array[0]
less = [i for i in array[1:] if i<= pivot]#由所有小于等于基准值的元素组成的数组
greater = [i for i in array[1:] if i> pivot]#由所有大于基准值的元素组成的子数组
return quicksort(less) + [pivot] + quicksort(greater) print(quicksort([10, 5, 2, 3]))

在这段代码里,首先满足递归条件时,取得一个基准数,基准数通常为数组的第一个元素,然后分成两个子数组,一个是小于等于基准数的子数组和大于基准数的子数组,不断进行递归调用对这两个子数组进行排序,最后得到排序好的数组。

书中讲解看完后,头脑里很快就有了思绪,但是当我想把上面的代码转换成C#时,就摸不着头脑,打脑壳的遭不住,因为在C#里并不能像上面一样简简单单的就实现,最主要的就是C#中数组不能通过直接相加来合并。

所以还是在网上看了不少C#快速排序的详解后写出了以下代码:

         /// <summary>
/// 快速排序对数组进行升序排序
/// </summary>
/// <param name="array">要排序的数组</param>
/// <param name="leftIndex">从左边遍历的第一个数的索引</param>
/// <param name="rightIndex">从右边遍历的第一个数的索引</param>
public static void QuickSort(int[] array, int leftIndex, int rightIndex)
{
if (leftIndex >= rightIndex)//基线条件
return;
int n = leftIndex;
int m = rightIndex;
int pivot = array[leftIndex];
while (n != m)
{
for (; n < m; m--)
{
if (array[m] < pivot)
{
array[n] = array[m];//交换位置
break;
}
}
for (; n < m; n++)
{
if (array[n] > pivot)
{
array[m] = array[n];
break;
}
}
}
array[n] = pivot;//循环完成后已经按照小于基准数和大于基准数左右排好序,基准数放中间。
QuickSort(array, leftIndex, n - );//对着两个子数组进行递归
QuickSort(array, n + , rightIndex);
}

网上快速排序的思路如上,甚至来说基线条件和我在书中看见的都已经完全不一样,并且和书中的逻辑也不太相同,只是依旧是分治法解决问题。

不仅是分出两个子数组,而是对当前的数组进行排序,排序过程也不好理解,从右至左循环,找出比基准数大的数,再从左至右循环,找出比基准数小的数,然后将两个数字调换位置,到最后只剩一个数的时候,就是基准数该在的位置,把基准数放到这个位置。

所以我足足想了2天,才能够独立写出上面的快速排序代码,不过我已经不知道我到底是真真切切理解了排序的思路,还是说因为看了太久,已经把排序的方式背在脑中了,真是悲哀,聪明的小伙伴一定一下就能学会,我却想了两天连自己也不清楚到底想明白没有了。

最后,我依旧有一个疑问,快速排序的时间复杂度是O(nlogn),那么上面的Python代码依旧是O(nlogn)吗?

新声明数组,然后将他们赋值,再合并,这样的操作会影响时间复杂度吗?

甚至我想用Linq语法

             int[] less = (from i in array where i < pivot select i).ToArray();
int[] greater = (from i in array where i > pivot select i).ToArray();

返回的数组甚至还是排好序的,那我直接用将这两个数组和基准数加起来不是更简单吗?我已经完全懵逼了,不知道时间复杂度是如何计算的,学习的长路真是漫漫啊!

c#中快速排序的学习的更多相关文章

  1. PHP中的Libevent学习

    wangbin@2012,1,3 目录 Libevent在php中的应用学习 1.      Libevent介绍 2.      为什么要学习libevent 3.      Php libeven ...

  2. JS中childNodes深入学习

    原文:JS中childNodes深入学习 <html xmlns="http://www.w3.org/1999/xhtml"> <head> <ti ...

  3. CNCC2017中的深度学习与跨媒体智能

    CNCC2017中的深度学习与跨媒体智能 转载请注明作者:梦里茶 目录 机器学习与跨媒体智能 传统方法与深度学习 图像分割 小数据集下的深度学习 语音前沿技术 生成模型 基于贝叶斯的视觉信息编解码 珠 ...

  4. 图解BERT(NLP中的迁移学习)

    目录 一.例子:句子分类 二.模型架构 模型的输入 模型的输出 三.与卷积网络并行 四.嵌入表示的新时代 回顾一下词嵌入 ELMo: 语境的重要性 五.ULM-FiT:搞懂NLP中的迁移学习 六.Tr ...

  5. python中confIgparser模块学习

    python中configparser模块学习 ConfigParser模块在python中用来读取配置文件,配置文件的格式跟windows下的ini配置文件相似,可以包含一个或多个节(section ...

  6. Scala中的类学习

    Scala中的类学习 从java了解类的情况下,了解Scala的类并不难.Scala类中的字段自动带getter和setter方法,用@BeanProperty注解生成javaBean对象的getXX ...

  7. Deep learning for visual understanding: A review 视觉理解中的深度学习:回顾 之一

    Deep learning for visual understanding: A review 视觉理解中的深度学习:回顾 ABSTRACT: Deep learning algorithms ar ...

  8. Java:类集框架中集合的学习

    Java:类集框架中集合的学习 集合 Java:Set的学习 Set是类集框架中的集合类.集合是不按特定的方式排序,并且没有重复对象的一种类. Q:Set如何操作?Set中的不按特定方式排序是怎么排序 ...

  9. OpenCV中Camshitf算法学习(补充)

    结合OpenCV中Camshitf算法学习,做一些简单的补充,包括: 实现全自动跟随的一种方法 参考opencv中的相关demo,可以截取目标物体的图片,由此预先计算出其色彩投影图,用于实际的目标跟随 ...

随机推荐

  1. UX设计秘诀之注册表单设计,细节决定成败

    以下内容由摹客团队翻译整理,仅供学习交流,摹客iDoc是支持智能标注和切图的产品协作设计神器. 说实话,现实生活中,又有多少人会真正喜欢填写表格?显然,并不多.因为填写表单这样的网页或App服务,并非 ...

  2. 通过SD卡来安装Linux系统

    一.制作SD启动卡(安装Linux)步骤: 烧写原理:superboot-6410.bin(bootloader)+内核镜像文件+根文件系统 1.将SD卡插入USB接口的读卡器,并插在PC的USB口 ...

  3. activiti 清库脚本(转)

    在使用activiti 的时候会经常遇到需要清空数据库中的数据,因此本文重点讲解如何解决该问题. 再删除数据的时候,需要注意有主外键约束的问题?下面罗列的DDL可以结合自身的业务需求进行灵活改造. D ...

  4. 利用PHPExcel读取excel文件

    $filePath = "7788.xls"; $PHPExcel = new PHPExcel(); $PHPReader = new PHPExcel_Reader_Excel ...

  5. GOIP connects with Elastix through “config by line”

    GOIP connects with Elastix through “config by line” By grace Liu on May 17, 2013 in Elastix, Gateway ...

  6. NOIP训练测试3(2017081601)

    上一波题还是比较水的吧?[?????] 也许吧! 但时间还是比较紧的,所以我从2.5个小时延长至3个小时了. 不管了,做题不能停,今天继续测试. 水不水自己看,我什么也不说(zhe shi zui h ...

  7. 协程的NullReferenceException 错误

    public void loadPic(string url) { WWW www = new WWW(url); StartCoroutine(WaitForRequest(www)); } IEn ...

  8. rails 新建user的phonenumber字段

    1.新建字段 //rails g migration add_字段名_to_表名 字段名:字段类型 rails g migration add_title_to_contents title:stri ...

  9. myeclipse部署项目的时候报No projects are available for deployment to this server但是项目明明存在

    如题,今天在尝试部署从SVN上down下来的项目时,发现不能被tomcat识别成web项目!原因是SVN上down下来的项目的结构并非典型的web项目.  解决办法,右键项目->properti ...

  10. 2018.11.07 NOIP训练 lzy的游戏(01背包)

    传送门 考虑对于每次最后全部选完之后剩下的牌的集合都对应着一种构造方法. 一个更接地气的说法: 设消耗的牌数为ttt,如果使用的牌的lll值之和也为ttt,则对应着一种构造方式让这种情形成立. 于是做 ...