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

我觉得就是很有道理,以前读书的时候,基本学完了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. 基于tomcat的solr环境搭建(Linux)

    ♥♥  solr是基于lucene的一个全文检索服务器,提供了一些类似webservice的API接口,用户可以通过http请求solr服务器,进行索引的建立和索引的搜索.索引建立的过程:用户提交的文 ...

  2. oracle 笔记DBA

    1.1oracle开启归档 关闭数据库 SQL>archive log list; SQL>shutdown immediate; SQL>startup mount ; SQL&g ...

  3. oracle的常用99条语句

    1. select * from emp; 2. select empno, ename, job from emp; 3. select empno 编号, ename 姓名, job 工作 fro ...

  4. 技术课堂】如何管理MongoDB数据库?

  5. Eventlog Analyzer日志管理系统、日志分析工具、日志服务器的功能及作用

    Eventlog Analyzer日志管理系统.日志分析工具.日志服务器的功能及作用 Eventlog Analyzer是用来分析和审计系统及事件日志的管理软件,能够对全网范围内的主机.服务器.网络设 ...

  6. Sencha extjs 的安装

    delphi 的母公司Idera 突然就把sencha extjs 收购了,这确实是一个很好的消息,意味着delphi 开始在web方面开始发力, 目前delphi 集成extjs 的呼声越来越强烈, ...

  7. 2019.02.07 bzoj4316: 小C的独立集(仙人掌+树形dp)

    传送门 题意:给出一个仙人掌森林求其最大独立集. 思路:如果没有环可以用经典的树形dpdpdp解决. fi,0/1f_{i,0/1}fi,0/1​表示第iii个点不选/选的最大独立集. 然后fi,0+ ...

  8. 2019.01.14 codeforces685B. Kay and Snowflake(树形dp)

    传送门 题意简述:给出一棵树,求每个子树的重心. 首先通过画图可以观察出一个性质,我们从叶子结点向根节点递推重心的话重心的位置是不会下降的. 然后由于一个点的重心要么是自己,要么在重儿子子树内,因此如 ...

  9. 2018.10.25 bzoj4517: [Sdoi2016]排列计数(组合数学)

    传送门 组合数学简单题. Ans=(nm)∗1Ans=\binom {n} {m}*1Ans=(mn​)∗1~(n−m)(n-m)(n−m)的错排数. 前面的直接线性筛逆元求. 后面的错排数递推式本蒟 ...

  10. JS将时间戳转化为时间

    //将时间戳转化为时间 function timestampToTime(timestamp) { var date = new Date(timestamp * 1000);//时间戳为10位需*1 ...