精华内容
下载资源
问答
  • 1. 当排除数据干扰性之后,若问,当排序的数组规模在10左右时,快速排序、归并排序、堆排序的运行时间是怎么样? 大多数人答曰:快速排序最快,归并次之,堆排序最慢。  好吧,基本应该是这样。   2. 若...

    1. 当排除数据的干扰性之后,若问,当排序的数组规模在10左右时,快速排序、归并排序、堆排序的运行时间是怎么样的?

    大多数人答曰:快速排序最快,归并次之,堆排序最慢。

            好吧,基本应该是这样的。

     

    2. 若问,当排序的数组规模在10左右且元素基本有序时,快速排序、归并排序、堆排序的运行时间是怎么样的?

    一部分人答曰:归并排序最快,快速排序次之,堆排序最慢。

            我想我会怎么回答呢?我不知道。

            当元素有序的时候,之所以说归并排序快,就是因为比较次数少了,减少到了逼近nlog(n)/2的规模,而此时对于快速排序和堆排序并不是最有利的,因为它们的比较次数还会是在O(nlogn)的规模,可能这样说也不太对(尤其是对于快速排序),但是比较次数比归并排序多应该是必然的。(根据大量程序的统计结果表明,一般快速排序的比较次数是归并排序的2倍!)但是,此时,只有10的规模,程序的运行时间跟算法的比较次数真的没有太大的关系。

     

     

    3. 当排除数据的干扰性之后,若问,当排序的数组规模在10000左右时,快速排序、归并排序、堆排序的运行时间是怎么样的?

    部分人答曰:快速排序最快、归并排序次之、堆排序最慢。

            快速排序之快大家早有耳闻,所以必须当仁不让。为什么归并次之呢?是啊,刚刚明明还说了一般快速排序的比较次数是归并排序的2倍,为什么快速排序反而比归并排序运行起来快呢?这得从程序的结构上来分析,归并比较次数确实少,但是在while循环时,要判断是否出界(而快速排序的while循环基本上是永远为true的,基本不必考虑这个问题,但是要考虑另一个较小的问题,下面再说),至少需要在此多做O(nlogn)这个规模的次数(我对这个具体数字也不是很确定,呵呵)比较,而且,归并排序额外占用了一个同等规模的数组,还要把数据拷贝回去,所以导致了速度明显慢于快速排序。

           那么,此时,归并排序和堆排序又该谁快呢?我试着写了一个C#的归并排序和堆排序,采用随机数生成了个10000大小的数组,发现,居然堆排序居然比归并排序快!当然,也许并不是如此,只是实验的偶然性,我并能保证我写的程序的其他条件是“平等的”。但是我宁愿相信归并排序还是比堆排序更快的。有时候,我们不必纠结于结果,而是应当了解这其中的缘由,既然已经发生了这样的情况,到底会是什么原因呢?我想会不会跟计算机体系结构有关呢?是不是因为Cache(高速缓冲存储器)呢?归并排序额外占用了一个同等规模的数组,所以空间复杂度是O(n),而堆排序理论上只需要一个一个比较时的临时空间,所以空间复杂度是常数级别O(1)。我们这里所说的快速排序、归并排序、堆排序都是内排序,数据都是在内存中完成比较,而为了体现“程序的局部性”原则,一般这些数据都会同时写在Cache中,虽然内存和Cache之间的速度是极快的,但是这样的间隙还是可以因为数据量的增大而被放大的。

     

     

    4. 当排除数据的干扰性之后,若问,当排序的数组规模在10000000左右时,快速排序、归并排序、堆排序的运行时间是怎么样的?

    这时候大部分都会答曰:堆排序最快、快速排序次之、归并排序最慢。

           说到此,似乎并没有什么话可说的了,确实,各种资料参考书上、各种网站链接上,都有“堆排序适合海量大数据的排序”此类云云。但是,“适合”难道就一定是最快的吗?

           我没做过实验,我不敢说,10000000规模的int数组其存储容量虽说还不大,但是也需要大概40M的空间,让自己有限的内存来玩这些事情有些捉襟见肘。我们也不必在乎到底是谁最快,我们的目标还是在于理解一些东西,即使我们很浅显。

     

           这个时候我们确实有理由,而且不少人的实验也证明了的,堆排序确实开始“快”起来了,而且已经超过了快速排序。那么我们得来分析一下为什么快速排序不再“快”起来了。关于这个就得从“怎么样才算是快的要素”说起。我们学过的一般的算法中,时间复杂度为O(logn)的算法应该算是最快的,比如二分搜索。所以,我们任何的问题如果可以映射成二分搜索类的,那么这个解决方案是相当完美的。二分搜索之所以好,是因为它每次几乎可以排除当前规模一半的可能性,使得解决过程中少走弯路。很显然,归并排序、堆排序并不符合这样的特征,而快速排序就有些许这样的特征。快速排序的核心就是轴元素pivot的选取,将所有大于轴元素的移到左边,其余移到右边。这里我引用了一下别人比较专业的话。快速排序的第一次比较就是将一个元素和轴元素比较,这个时候显而易见的是,“大于”和“小于”的可能性各占一半。然而,快速排序的第二次比较就不那么高明了:我们不妨令轴元素为pivot,第一次比较结果是a1<pivot,那么可以证明第二次比较a2也小于pivot的可能性是2/3!这容易证明:如果a2>pivot的话,那么a1,a2,pivot这三个元素之间的关系就完全确定了——a1<pivot<a2,剩下来的元素排列的可能性我们不妨记为P(不需要具体算出来)。而如果a2<pivot呢?那么a1和a2的关系就仍然是不确定的,也就是说,这个分支里面含有两种情况:a1<a2<pivot,以及a2<a1<pivot。对于其中任一种情况,剩下的元素排列的可能性都是P,于是这个分支里面剩下的排列可能性就是2P。所以当a2<pivot的时候,还剩下2/3的可能性需要排查。所以,快速排序并不像二分搜索那样完美,它每次排除的可能性越来越小,而且反复交换之中带来的时间开销也逐渐显现,所以,有理由相信,它快不起来。

           为什么堆排序此时可堪大任呢?首先堆排序是一个线程稳定的,存取稳定的(虽然是不稳定排序算法),在堆排序的过程中,基本不太会发生对程序具有Fatal Destroy的事情来,这一点归并排序就不行,这个规模下的归并排序可能会发生内存溢出的问题。既然牺牲了效率,就必然带来安全性方面的完善。堆的建立与调整是一个反复循环的过程,但是堆也是一种数据结构,既然是数据结构,就拥有先天性的一些优势。这些优势,有些是看不见的,无法在程序代码中体现的,那会体现在哪里呢?可能会体现在程序编译运行时,体现在数据存储与读取时。数据在内存中的分配无非就是堆式栈式此类云云。一般的数组我们认为都是分配在栈上的,是一片连续的区域。但是,我想的问题是,这个规模的数组真的完全是连续分配在栈上的吗?别多想了,此事与本主题无关。

     

     

    哎,说了这么多废话(有些话禁不起推敲,有些错误),无非就是想表明几点:

    1. 不以时间复杂度论程序运行的快慢

    2. 就效率而言,递归分治的思想必然优于迭代循环

    3. 程序运行时发生的事情大多对我们来说都是透明的,大多情况下我们唯一能看到的就是结果

    4. 排序算法的存在不仅仅是给数据排序,同时还在给程序员的能力进行排序

     


     

    展开全文
  • 常见的排序算法有选择排序、快速排序、希尔排序、堆排序、冒泡排序、插入排序、归并排序和基数排序。 快速排序的应用: 补充知识: 结构体: typedef struct Pat{ int num; string sid; int age; }PAT; //相当于...

    排序

    1. 排序是一个基础算法,是贪心和二分算法的基础
    2. 排序是将输入数据,按照某种条件变成有序序列
    3. 一般不会手写排序,会调用函数
    4. 常见的排序算法有选择排序、快速排序、希尔排序、堆排序冒泡排序、插入排序、归并排序基数排序

    快速排序的应用:

    补充知识
    sort:
    algorithm 默认是从小到大

    • 对于int arr[10] 数组,sort(a, a+10);
    • 对于vector <int> v(10) , sort(v.begin(),v.end());
      传入了参数cmp后,根据cmp进行排序
    bool cmp(int a, int b){//cmp函数返回的值是bool类型
    	return a>b; //从大到小排列,不能写成含有等号的不等式,sort是不稳定的排序
    }
    

    结构体:

    typedef struct Pat{
    	int num;
    	string sid;
    	int age;
    }PAT; //相当于struct Pat 
      
    PAT pt[mMax] //定义一个结构体变量 mMax结构体数组的大小 
    
    for(int i=0;i<n;i++){
    		cout<<pt[i].sid<<endl; }//结构体的遍历
    

    例题解析:

    2019年北大叉院机试签到题 C - 病人排队

    试题内容:

    病人登记看病,编写一个程序,将登记的病人按照以下原则排出看病的先后顺序:
    老年人(年龄 \ge 60≥60 岁)比非老年人优先看病。
    老年人按年龄从大到小的顺序看病,年龄相同的按登记的先后顺序排序。
    非老年人按登记的先后顺序看病。

    input

    第 11 行,输入一个小于 100100 的正整数,表示病人的个数;
    后面按照病人登记的先后顺序,每行输入一个病人的信息,包括:一个长度小于 1010 的字符串表示病人的 ID(每个病人的 ID 各不相同且只含数字和字母),一个整数表示病人的年龄(不超过 100100 岁),中间用单个空格隔开。

    output

    按排好的看病顺序输出病人的 ID,每行一个。
    输出时每行末尾的多余空格,不影响答案正确性

    Sample Input

    5
    021075 40
    004003 15
    010158 67
    021033 75
    102012 30

    Sample Output

    021033
    010158
    021075
    004003
    102012

    题目坑点:按照登记的先后顺序是按照输入的顺序;

    则运用的是稳定排序,可以用冒泡排序,插入排序,归并排序和基数排序
    不稳定排序:选择排序,快速排序,希尔排序,堆排序。

    解题方法

    1. 运用简单的稳定排序,冒泡法:
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 110;
    struct patient {
    	char no[13];
    	int age;
    };
    patient a[maxn];
    patient b[maxn];
    
    int main() {
    	int n;
    	scanf("%d", &n);
    	patient t;
    	int lena = 0;
    	int lenb = 0;
    	for (int i = 0; i < n; i++) {
    		scanf("%s", t.no);
    		scanf("%d", &t.age);
    		if (t.age >= 60) a[lena++] = t;
    		else b[lenb++] = t;
    	}
    	for (int i = 0; i < lena; i++) {
    		for (int j = 0; j < lena- i-1; j++) {
    			if (a[j].age < a[j+1].age) {
    				t = a[j];
    				a[j] = a[j+1];
    				a[j+1] = t;
    			}
    		}
    	}
    	for (int i = 0; i < lena; i++) printf("%s\n", a[i].no);
    	for (int i = 0; i < lenb; i++) printf("%s\n", b[i].no);
    	return 0;
    }
    
    1. 运用不稳定排序,sort自己定义一个结构体,增加序列号
    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <algorithm>
    using namespace std;
    const int mMax = 101;
    typedef struct Pat{
    	int num;
    	string sid;
    	int age;
    }PAT; 
    int n; 
    PAT pt[mMax];
    bool cmp(PAT a,PAT b){
    	if(a.age>=60&&b.age>=60){
    		return a.age==b.age? a.num<b.num:a.age>b.age;
    	}
    	else if(a.age>=60||b.age>=60){
    		return a.age>b.age;
    	}
    	else return a.num<b.num;
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=0;i<n;i++){
    		pt[i].num = i;
    		cin>>pt[i].sid>>pt[i].age;
    	}
    	sort(pt,pt+n,cmp);
    	for(int i=0;i<n;i++){
    		cout<<pt[i].sid<<endl;
    	}
    	return 0;
    }
    

    勉励:
    一切才刚刚开始,加油!ヾ(◍°∇°◍)ノ゙

    如果觉得我的文章对你有所帮助与启发,点赞给我个鼓励吧(づ ̄3 ̄)づ╭❤~
    关注我和我一起共勉加油吧!
    如果文章有错误,还望不吝指教!

    展开全文
  • 那些我们学过的排序算法 在我们校园招聘的时候,大多数的面试官对于一个校招生都可能会问过类似的问题。比如,快排的思路呀,快排的实现呀。当然还有其他的一些经典排序吧! 可能会有很多的同学会想到问这些有...

    那些年我们学过的排序算法

      在我们校园招聘的时候,大多数的面试官对于一个校招生都可能会问过类似的问题。比如,快排的思路呀,快排的实现呀。当然还有其他的一些经典排序吧!
      可能会有很多的同学会想到问这些有什么用吗?因为大多数的时候我们不需要自己写这些排序的呀!
    主要问题有两个:
       1. 这些你可能都不知道。
       2. 不是为了问你具体的实现。
       这些东西其实仅仅是为了看一下你是否真的努力学习过了解过。其次,这个东西能不能理解体现着你的理解和学习能力的。如果这些东西你都不知道的话?那么你还怎么去理解更加复杂,更加难懂的业务流程呢?
      前面我们说过了这些东西的作用和为什么要知道这些东西。下面我们来说一下这些个算法吧!
    首先,我们要对排序算法做一个分类。就按照稳定性来分吧!
    不稳定的排序算法有以下几个:
       1. 选择排序
       2. 快速排序
       3. 堆排序
       4. 希尔排序
    稳定的排序算法:
       1. 冒泡排序
      2. 插入排序
       3. 归并排序
       4. 基数排序
    什么叫稳定的排序,稳定排序就是排序前后两个相等的数字的相对位置不变化。
    时间复杂度,经典排序算法的时间复杂度。

    算法 最优 平均 最差 空间复杂度 备注
    冒泡排序 o(n) o(n2) o(n2) o(1) 这里最优是优化过的排序
    插入排序 o(n) o(n2) o(n2) o(1)
    希尔排序 o(n) o(n1.3)o(n2) o(1)
    选择排序 o(n) o(n2) o(n2) o(1)
    堆排序 o(n) o(n*log2*n) o(n*log2*n) o(1) 这里的空间复杂度是在不使用递归的情况下的如果使用递归就和递归深度有关了。
    快速排序 o(n*log2*n) o(n*log2*n) o(n2) o(log2*n~0(n))
    基数排序 o(d(r+n)) o(d(r+n))) o(d(r+n)) o(rd+n)
    归并排序 o(n*log2*n) o(n*log2*n) o(n*log2*n) o(n)

    具体实现网上代码很多就不给出了。大家尽可以去度娘那里获取答案~~谢谢支持!

    展开全文
  • 那些我们一起学的排序

    千次阅读 2017-08-17 20:34:21
    选择 冒泡 插入 排序 快速 归并 桶 堆 STL

    目录

    前言

    排序是我们很早就学的一个几个东西了,虽然说都没什么用,但还是要总结的对不对。于是我开心地开启了放水之旅。

    选择排序

    §思想

    不断从无序序列中找出最小的一个,加入有序序列中。

    §分析

    特点:
    - 慢(平均时间复杂度O(n2))
    - 没什么用(一般不会用到这种排序方法)
    - 不稳定
    - 代码太长(相比STL的sort)
    (似乎都是缺点。。。来几个优点吧)
    - 简单
    - 不用思考
    - 容易理解
    - 一点都不难
    (这是不是应该算一个优点啊)

    冒泡排序

    §思想

    重复交换相邻的两个反序元素,最终成为正序。

    §分析

    特点:
    - 慢(平均时间复杂度O(n2))
    - 没什么用(一般不会用到这种排序方法)
    - 不!稳定
    - 代码太长(相比STL的sort)
    - 简单
    - 不用思考
    - 容易理解
    - 一点都不难
    (你一定没有发现相比选择排序的§分析,我只是加了一个标点符号)

    插入排序

    §思想

    把无序数列一个个放到有序数列的相应位置。

    §分析

    • 慢(平均时间复杂度O(n2))
    • 没什么用(一般不会用到这种排序方法)
    • 不!稳定
    • 代码太长(相比STL的sort)
    • 简单
    • 不用思考
    • 容易理解
    • 一点都不难
      (你一定没有发现相比冒泡排序的§分析,我什么都没有改动)
    • 类似某些人玩牌时整理手中纸牌的过程。
      (还是改一下下吧)☝

    插排的师傅希尔排序

    §思想

    分组插入排序

    §分析

    • 慢(平均时间复杂度O(n2))
    • 没什么用(一般不会用到这种排序方法)
    • 不稳定
    • 代码太长(相比STL的sort)
    • 没有其他算法那么有名(或许事实不是这样,反正我是这么认为的)

    快速排序

    §思想

    将要排序的数据分割成一部分比另一部分都要小的两部分,然后左右各自递归调用。

    §分析

    • 快(平均时间复杂度O(nlogn)
    • 简单
    • 不用思考
    • 容易理解
    • 一点都不难
    • 不稳定

    归并排序

    §思想

    二路归并排序:将数列两两归并,然后再次两两归并直到有序为止二路归并排序。

    §分析

    • 较快(平均时间复杂度O(nlogn))
    • 不!稳定
    • 代码太长(相比STL的sort)
    • 简单
    • 不用思考
    • 容易理解
    • 一点都不难
    • 求逆序对思想
    • 比较有用

    比快排还快的桶排序

    §思想

    似乎有点不好说啊,那就不说了。

    §分析

    • 快(时间复杂度O(n))
    • 简单
    • 容易实现
    • 代码较短
    • 不用思考
    • 容易理解
    • 常用
    • 使用有范围(数,实数,有理数,整数,非负数,不能太大)
    • 快速排序颜面扫地.(同在排序家族,抬头不见低头见的,何必呢!)

    堆排序

    §思想

    利用堆这种数据结构所设计的一种排序算法。

    §分析

    • 不稳定
    • 比较快(平均时间复杂度O(nlogn))
    • 代码太长(相比STL的sort)
    • 简单
    • 不用思考
    • 容易理解
    • 一点都不难

    我们最常用的排序 迷之微笑

    §实现

    (§思想和§分析被§实现篡位了)

    #include<algorithm>
    using namespace std;
    void s6o6r6t6(int a[],int f,int l)
    {
        sort(a+f,a+l+1);
    }

    本文最有用的一段话, 快来看啊! 快来看啊! 快来看啊! 快来看啊! 快来看啊! 快来看啊! 快来看啊! 快来看啊!

    本篇文章或许会出现各种各样奇葩的错误。
    如果读者能理解我,请点个赞,谢谢。
    如果读者不能理解我,我相信点了赞之后你还是不能理解我,为了让你养成不忘初心的好习惯,请点个赞,谢谢。

    展开全文
  • 内容提要:文章介绍excel时间排序分别按和月讲解时间排序方法。对Excel感兴趣朋友可加Excel学习交流群:284029260(www.itblw.com)  有时我们因工作原因需要进行excel时间排序。  第一,excel时间排序...
  • 程序员那些必须掌握的排序算法(下)

    万次阅读 多人点赞 2019-08-25 17:52:14
    接着上一篇的排序算法,我们废话不多,直接进入主题。 1.快速排序 快速排序(Quicksort)是对冒泡排序的一种改进。 快速排序由C. A. R. Hoare在1960提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的...
  • 动画 | 大学四结束之前必须透彻的排序算法

    千次阅读 热门讨论 2019-11-12 08:35:38
    现如今大学生学习排序算法,除了学习它的算法原理、代码实现...本章主要从如何分析一个算法开始入手,从而循进渐进的分析那些大学四结束之前必须掌握的排序算法! 文章目录如何分析一个“排序算法”?1、排序算法...
  • 排序算法:快速排序

    万次阅读 多人点赞 2018-04-24 22:02:57
    手写排序算法几乎是程序员面试必问的题目,大多数人都会选择写冒泡排序,如果此时你写的是其他改进过的排序算法,相信会让面试官眼前一亮。本文将介绍常见的排序算法中的“快速排序”。 基本思想 快速排序...
  • 用Objective-C实现几种基本的排序算法,并把排序的过程图形化显示。其实算法还是挺有趣的 ^ ^. 选择排序冒泡排序插入排序快速排序 选择排序 以升序为例。 选择排序比较好理解,一句话概括就是依次按位置挑选...
  • 计数排序

    万次阅读 2020-06-26 08:47:32
    冒泡、选择、插入、归并、快速、希尔、堆排序,都是基于比较的排序,平均时间复杂度最低是O(nlogn)。 计数排序、桶排序、基数排序,都不是基于比较的排序,它们是典型的用空间换时间,在某些时候,平均时间复杂度...
  • 那些我们一起学过排序算法” 排序算法是经常使用算法,在STL中也有一个比较牛X快速排序(sort),但是我们不能只会调用sort呀!?作为一个好学同学,我们要知道各种排序的内部是怎么实现滴~~~提到...
  • 希尔排序是希尔(Donald Shell)于1959提出一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后一个更高效版本,也称为缩小增量排序,同时该算法是冲破O(n2)第一批算法之一。它与插入...
  • 这篇文章主要介绍了Python实现快速排序和插入排序算法及自定义排序的示例,自定义排序用到了Pythonsort和sorted函数,需要朋友可以参考下 一、快速排序 快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. ...
  • 计数排序是一个非基于比较的排序算法,该算法于1954由 Harold H. Seward 提出,它的优势在于在对于较小范围内的整数排序。它的复杂度为Ο(n+k)(其中k是待排序数的最大值),快于任何比较排序算法,缺点就是非常...
  • 算法上,最基础就是排序算法,几乎在面试中,或多或少会要求你手写一些基础算法。今天鱼哥带大家这些基础算法回顾下。 快速排序 介绍: 快速排序(Quicksort)是对冒泡排序的一种改进。 快速排序由C. A. R. Hoare...
  • 计数排序是一个非基于比较的排序算法,该算法于1954由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。当然这是一种牺牲...
  • UVA11462排序

    2014-12-30 17:15:21
     给你200w个人年龄,年龄范围是1-100,然后让你从小到大排序输出所有人年龄,题目还特意强调输入文件限制25MB,题目内存限制2MB. 思路:  比较经典又简单一个题目了,很早以前就见过了,我们可以开...
  • 相关阅读:Python冒泡排序和插入排序算法 前言 昨天分享了我之前学习和写python中冒泡排序和插入排序,今天继续来分享一下希尔排序和选择排序方法。 希尔排序 希尔排序(Shell Sort)是插入排序的一种。也称...
  • 排序算法:归并排序

    2019-06-07 13:48:13
    前言 这篇文章本该发表于20184月份末...本文将介绍另一个高效的排序算法——“归并排序”。 基本思想 归并排序的主要思想是分治法。主要过程是: 将n个元素从中间切开,分成两部分。(左边可能比右边多1个...
  • 04华为一道排序题..

    千次阅读 2007-09-06 22:29:00
    华为应该是几一道排序题目了,不知道转者从那里转来,给出解法有点错误,没有考虑到数组越界问题,并且排序中也不应该出现负数情况。转帖地址见于http://blog.csdn.net/upwaker/articles/57731.aspx ...
  • 基于桶基数排序

    2019-02-11 08:30:31
    前言 推出一个新系列,《看图轻松理解...基数排序(Radix Sort)算法是一种非比较的排序算法,早在 1887 Herman Hollerith 就已经在打孔卡片制表机中使用该算法。一般多用于对整数的排序,但由于整数与某些字符...
  • 排序算法在题目中经常需要用到,在程序中,我们一般打的是快排,归并,堆排等高效率排序,更有甚者会直接用sort排序,而今天,我要介绍一种奇特的排序方法——Monkey King 排序,我相信接下来的内容会对你有一定帮助...
  • 基本思想 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。...D.L.shell于1959在以他名字命名的排序算法中实现了这一思想。算法先将
  • 快速排序的原理

    2019-09-11 16:51:17
    基本思想是:通过一趟排序将要排序的数据分割成独立两部分,其中一部分所有数据都比另外一部分所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,977
精华内容 5,190
关键字:

年的排序