liujae个人页面-阿里云开发者社区

个人介绍

暂无个人介绍

擅长的技术

获得更多能力
通用技术能力:

暂时未有相关通用技术能力~

云产品技术能力:

暂时未有相关云产品技术能力~

阿里云技能认证

详细说明
  • 高分内容
  • 最新动态
  • 文章
  • 问答
正在加载, 请稍后...
滑动查看更多
正在加载, 请稍后...
暂无更多信息
  • 发表了文章 2017-08-02

    【Science】算法揭秘深度学习大牛,谁影响了谁?

  • 发表了文章 2017-08-02

    【教程】怎么获得人工智能最前沿资讯

  • 发表了文章 2017-08-02

    【Nature】AlphaGo赢了围棋,但玩量子计算游戏人的直觉强过机器

  • 发表了文章 2017-08-02

    IBM 发布首个深度学习类脑超级计算平台 IBM TrueNorth

  • 发表了文章 2017-08-02

    【智驾深谈】Mobileye,用单目视觉点亮自动驾驶

  • 发表了文章 2017-08-02

    【珍藏】CMU大师对软件工程师的系统建议(附书和论文下载)

  • 发表了文章 2017-08-02

    【六大重构】李彦宏挂帅人工智能,一张图看懂百度五年架构变迁

  • 发表了文章 2017-08-02

    【英年早逝】英国AI天才David Mackay昨日去世

  • 发表了文章 2017-08-02

    李立军:用“串珍珠理论”做中国人工智能产业投资 | 新智元智库专家访谈

  • 发表了文章 2017-08-02

    【新智元招聘】60万年薪招聘主编(主笔、高级编译、咨询总监、客户经理)

  • 发表了文章 2017-08-02

    【国务院会议】李克强点名机器人产业,中日美三国争霸

  • 发表了文章 2017-08-02

    【20 亿美元赌注】英伟达推出深度学习芯片,人工智能进入主流时代

  • 发表了文章 2017-08-02

    【新智元人工智能创业家】驭势吴甘沙:如何突围自动驾驶汽车?

  • 发表了文章 2017-08-02

    camLine赢取中国建材碲化镉薄膜厂制造软件合同

  • 发表了文章 2017-08-02

    Gamesa宣布获得130MW印度最大太阳能光伏EPC合同

  • 发表了文章 2017-08-02

    夏普推出高效太阳能椅 转换效率高达30%

  • 发表了文章 2017-08-02

    太阳能光伏电池板将撑起白银需求

  • 发表了文章 2017-08-02

    阿科玛在中国提升Kynar氟聚合物产能

  • 发表了文章 2017-08-02

    CFCA入根苹果 信息安全产品国产化的又一重大突破!

  • 发表了文章 2017-08-02

    罗兰贝格推出Terra Numerata平台 探索大数据商业化

正在加载, 请稍后...
滑动查看更多
  • 回答了问题 2019-07-17

    二进制11*11=1001怎样算出来

    跟平时乘法打草稿时一样。。
    踩0 评论0
  • 回答了问题 2019-07-17

    软件工程出来能做算法工程师吗 知乎

    一般不会有明确设限,相应的技能过硬才是关键。
    态度、主动学习意愿和快速学习的能力,往往更被看中,而非单纯的专业。
    踩0 评论0
  • 回答了问题 2019-07-17

    c#利用快速排序法对给定的一个整数数组进行排序

    百度人才多啊,这个问题两个人都对,但楼主都不会选最佳答案的,因为题目同读清楚。

     

    先发一些牢骚:拿C#来做排序算法,就算算法再怎么好也不会得到好的性能。一般研究算法时最好在C/C++中,用这个研究算法没有多大的意义。

     

    再说概念:快速排序法是一种不稳定排序算法,一楼用冒泡算法进行排序的,二楼用的类库直接排序的,开发上是快速一点,但楼主可能只是想研究一下快速排序算法而已。

     

    算法特点:先选定一个关键词,比关键词大的放在关键词的右边,否则放在关键词的左边,这为第一次排序,然后用递归法分别将左边与右边的再进行同样排序。

      public void QuickSort(int[] array,int low,int high)
    {
    if(low>= high) return;
    int key = array[low] ; //假定关键词
    int i = low,j=high;
    while(i<j)
    {
    while(key < array[j]) j--; //找到从后边第一个小于关键词的元素
    while(array[i]<key) i++; //找到从前边第一个大于关系词的元素
    if(i>=j) break; //关键词已经排好序,跳出
    //没有排好序的要进行交易,将一个小于关键词的前边一个大于关键词的值与后边一个小于关键词的值进行交换
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    //继续循环,直到i>=j
    }//该次保证了第一次循环,出现两前半部分大于关键词,后半部分小于关键词的情况。
    QuickSort(array,low,j); //排序前半段
    QuickSort(array,j+1,high); //排序后半段
    }

    可以看出实现了分段递归的方式再进行调用。

    程序说明,因为前边有low>=high的判断的,其实与while(i<j)是重复的。所以该条件中的i<j可以改为true;而循环体中的i>=j bread;也能保证跳出。

    踩0 评论0
  • 回答了问题 2019-07-17

    电脑高手来`啊

    RSA是一个加密算法。它是一种非对称加密算法。在公钥加密标准和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特、阿迪·萨莫尔和伦纳德·阿德曼一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人名字开头字母拼在一起组成的。
    具体信息你可以上网上搜索看看
    踩0 评论0
  • 回答了问题 2019-07-17

    DES RSA PGP的异同 电子商务用哪种方式多一些?

    你是华工电商的吧……你是哪个班啊
    踩0 评论0
  • 回答了问题 2019-07-17

    二进制运算中“∧”是什么意思?

    ∧是与的意思,0∧A=0 1∧A=A
    ∨是或的意思,0∨A=A 1∨A=1
    (按位来求)
    结果为:01011001∧10100111=0000 0001
    踩0 评论0
  • 回答了问题 2019-07-17

    排序法的排序法的基本步骤

    排序法是根据一些特定的标准(例如工作的复杂程度、对组织的贡献大小等对各个职位的相对价值)进行整体比较,进而将职位按照相对价值的高低排列出一个次序。其基本步骤是:
    1、对排序的标准达成共识。虽然排序法是对岗位的整体价值进行评价而排序,但也需要参与评估的人员对什么样的“整体价值”更高达成共识,如责任更大,知识技能更高,工作更加复杂,环境因素恶劣等。
    2、选定参与排序的职位。如果公司较小可以选取全部职位进行排序。
    3、评定人员根据事先确定评判标准,对公司同类岗位的重要性逐一作出评判,最重要的排在第一位,次要的、再次要的顺次往下排列。
    4、将经过所有评定人员评定的每个岗位的结果加以汇总,得到序号和。然后将序号和除以评定人数,得到每一岗位的平均序数。最后,按平均序数的大小,由小到大评定出各岗位的相对价值的次序。

    踩0 评论0
  • 回答了问题 2019-07-17

    请问谁有Gps电路工作原理图!!!

    先采纳在回答
    踩0 评论0
  • 回答了问题 2019-07-17

    数据结构与算法分析c++描述第三版怎么样

    我们上课就是用这本,前面还好,就一两个算法稍微烦一点。不过外国人写的书看起来逻辑有点别扭,编码习惯也有点不同,建议你看清华上课用的数据结构教程
    踩0 评论0
  • 回答了问题 2019-07-17

    算法工程师工资怎么样

    IT行业最高,但门槛也很高
    踩0 评论0
  • 回答了问题 2019-07-17

    箱排序算法程序

    /*假设一个链表中包含了一个班级内所有的学生的信息,每个结点含有以下数据域 ?
    学号、姓名、各门课成绩以及平均分(假定所有的分数均为0-100的整数),
    设计程序用箱排序对指定的成绩排序,并输出排序结果。
    基本要求:
    (1)每个箱子(0-100)描述成一个链表;
    (2)能够从欲排序链表的首部开始,逐个删除每个结点,并把所删除的结点放入适当的箱子中。
    (3)收集并链接每个箱子中结点,产生一个排序的链表并输出结果。*/
    #include<stdlib.h>
    #include<stdio.h>
    struct studentnode /*学生信息节点*/
    {
    char name[10];
    char num[19];
    int math;
    int eng;
    int os;
    int aver;
    struct studentnode * next;
    };
    typedef struct studentnode studentnode;
    typedef struct studentnode * nodelink;
    typedef struct boxhead{
    studentnode *tail;
    }boxnode;
    boxnode box[101]; /*箱子组合,每个元素指向一个箱子链表 */
    typedef struct head{
    studentnode *tail;
    }headnode;
    headnode head;
    int initial(FILE *fp)
    {
    studentnode *p;
    head.tail =NULL;
    while(!feof(fp))
    {

    p=malloc(sizeof(studentnode));
    if(fscanf(fp,"%s%s%d%d%d",p->num,p->name,&(p->math),&(p->eng),&(p->os))!=5)
    {
    printf("文件不完整\n");
    exit(0);
    }
    if(p->eng >100||p->eng <0||p->math >100||p->math <0||p->os >100||p->os <0)
    {
    printf("文件中的成绩不合法:应该是0——100之间的数字\n");
    exit(0);}
    p->aver=(p->math+p->eng+p->os)/3;
    p->next=head.tail ;head.tail=p;
    }
    return 1;
    }
    int inbox(int choose) /*从欲排序链表的首部开始,逐个删除每个结点,并把所删除的结点放入适当的箱子中*/
    {
    int i;
    studentnode *p,* p1;
    for(i=0;i<101;i++)
    {box[i].tail=NULL;}
    switch(choose) /*四种选择的不同处理*/
    {
    case 1:for(p1=head.tail;p1!=NULL;)
    {
    p=p1;
    p1=p1->next;
    p->next=box[p->math].tail;
    box[p->math].tail=p; /*逐个更改每个结点的指针,把它挂到相应的箱子中*/
    }
    break;
    case 2: for(p1=head.tail;p1!=NULL;)
    {
    p=p1;
    p1=p1->next;
    p->next=box[p->eng].tail;
    box[p->eng].tail=p;
    }
    break;
    case 3:for(p1=head.tail;p1!=NULL;)
    {
    p=p1;
    p1=p1->next;
    p->next=box[p->os].tail;
    box[p->os].tail=p;
    }
    break;
    case 4:for(p1=head.tail;p1!=NULL;)
    {
    p=p1;
    p1=p1->next;
    p->next=box[p->aver].tail;
    box[p->aver].tail=p;
    }
    break;
    default:printf("你的选择不合法 。\n");break;
    }

    return 1;
    }
    int outbox() /*收集并链接每个箱子中结点,产生一个排序的链表并输出结果。*/
    {
    studentnode *p1,*p;
    int i;
    head.tail=NULL;
    for(i=0;i<101;i++)
    {
    for(p=box[i].tail;p!=NULL;)
    {
    p1=p;
    p=p->next;
    p1->next=head.tail;
    head.tail=p1;
    }
    }
    return 1;
    }

    int main()
    {
    int choose;char c;
    FILE *fp;
    studentnode *p;
    if((fp=fopen("student.txt","r"))==NULL)
    printf("你的数据文件不存在。\n");
    else
    {
    initial(fp);
    do{
    do{
    printf("请输入你要按什么来排序:1:数学 2:英语 3:操作系统 4:平均分\n");
    scanf("%d",&choose);
    inbox(choose);
    }while(choose<0||choose>4);
    outbox();
    printf("按你的要求箱排序后的排名如下(从高到低) :\n");
    printf("学号 \t姓名\t数学\t英语\t操作系统\t平均分\n");
    for(p=head.tail;p!=NULL;p=p->next)
    printf("%s \t%s \t%d \t%d \t%d \t%d\n",p->num,p->name,p->math,p->eng,p->os,p->aver);

    printf("继续查询请按y或Y\n退出请按任意键:");
    getchar();
    scanf("%c",&c);
    }while(c=='y'||c=='Y');
    }
    }

    晕, 你要用类来实现? 如果不是, 把printf 和 scanf 改为 cout和cin , 再把头文件该过来, 不就行了 . ..
    踩0 评论0
  • 回答了问题 2019-07-17

    数据结构与算法:用筛选法建最小值堆,共交换元素多少次

    int[] a = { 38, 64, 52, 26, 73, 40, 48, 55, 15, 12 };

                for (int i = 0; i < a.Count() - 1; i++)
                {
                    if (a[i] <= a[i + 1])
                    {
                        var temp = a[i];
                        a[i] = a[i + 1];
                        a[i+1] = temp;
                    }
                }

                var sss = a;


    sss就是你想要的结果 循环的次数就是交换的次数

    踩0 评论0
  • 回答了问题 2019-07-17

    各种排序算法最好和最坏情况比较

    网上资料如此之多,百度一下,你就知道.
    踩0 评论0
  • 回答了问题 2019-07-17

    二进制计算101110111/1101 求竖式过程

    101110111(2)÷1101(2)=11100(2)……1011(2),

    换算为十进制,是375÷13=28……11。

    ————

    请点个采纳呗

    踩0 评论0
  • 回答了问题 2019-07-17

    在rsa算法中 已知 p=101 q=97 e=13 求d? 最好给出算法

    1477我用excel直接拉出来的
    踩0 评论0
  • 回答了问题 2019-07-17

    Android中自带的RSA加密算法和JAVA中的不是一个标准的吗

    java
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    android
    Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");

    参考:
    http://stackoverflow.com/questions/6069369/rsa-encryption-difference-between-java-and-android

    http://stackoverflow.com/questions/2956647/rsa-encrypt-with-base64-encoded-public-key-in-android

    android中RSA调用方法

    // Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    踩0 评论0
  • 回答了问题 2019-07-17

    如何用计算器计算二进制数的运算

    打开计算器,然后点"查看",选择"科学型"
    踩0 评论0
  • 回答了问题 2019-07-17

    动车快还是高铁快?动车和高铁的票价是多少?哪个贵?

    动车是一种车
    高铁是一种路
    小轿车快还是高速公路快。
    你所说的高铁,指的是高速动车组,他也是动车组的一种。轿车快还是汽车快。轿车不也是汽车吗。
    G比D一般是快一些的,价格也贵一些
    踩0 评论0
  • 回答了问题 2019-07-17

    快速排序算法的示例代码

        using System;     using System.Collections.Generic;     using System.Linq;     using System.Text;    namespace test{    class QuickSort    {        static void Main(string[] args)        {            int[] array = { 49, 38, 65, 97, 76, 13, 27 };            sort(array, 0, array.Length - 1);            Console.ReadLine();        }        /**一次排序单元,完成此方法,key左边都比key小,key右边都比key大。         **@param array排序数组          **@param low排序起始位置          **@param high排序结束位置         **@return单元排序后的数组 */        private static int sortUnit(int[] array, int low, int high)        {            int key = array[low];            while (low < high)            {                /*从后向前搜索比key小的值*/                while (array[high] >= key && high > low)                    --high;                 /*比key小的放左边*/                array[low] = array[high];                   /*从前向后搜索比key大的值,比key大的放右边*/                while (array[low] <= key && high > low)                    ++low;                 /*比key大的放右边*/                array[high] = array[low];            }            /*左边都比key小,右边都比key大。//将key放在游标当前位置。//此时low等于high */            array[low] = key;            foreach (int i in array)            {                Console.Write({0}\t, i);            }            Console.WriteLine();            return high;        }            /**快速排序 *@paramarry *@return */        public static void sort(int[] array, int low, int high)        {            if (low >= high)                return;             /*完成一次单元排序*/            int index = sortUnit(array, low, high);             /*对左边单元进行排序*/            sort(array, low, index - 1);            /*对右边单元进行排序*/            sort(array, index + 1, high);        }    }} 运行结果:27 38 13 49 76 97 65
    13 27 38 49 76 97 65  13 27 38 49 65 76 97
    快速排序就是递归调用此过程——在以49为中点分割这个数据序列,分别对前面一部分和后面一部分进行类似的快速排序,从而完成全部数据序列的快速排序,最后把此数据序列变成一个有序的序列,根据这种思想对于上述数组A的快速排序的全过程如图6所示:
    初始状态 {49 38 65 97 76 13 27} 进行一次快速排序之后划分为 {27 38 13} 49 {76 97 65} 分别对前后两部分进行快速排序{27 38 13} 经第三步和第四步交换后变成 {13 27 38} 完成排序。{76 97 65} 经第三步和第四步交换后变成 {65 76 97} 完成排序。图示 快速排序的最坏情况基于每次划分对主元的选择。基本的快速排序选取第一个元素作为主元。这样在数组已经有序的情况下,每次划分将得到最坏的结果。一种比较常见的优化方法是随机化算法,即随机选取一个元素作为主元。这种情况下虽然最坏情况仍然是O(n^2),但最坏情况不再依赖于输入数据,而是由于随机函数取值不佳。实际上,随机化快速排序得到理论最坏情况的可能性仅为1/(2^n)。所以随机化快速排序可以对于绝大多数输入数据达到O(nlogn)的期望时间复杂度。一位前辈做出了一个精辟的总结:“随机化快速排序可以满足一个人一辈子的人品需求。”
    随机化快速排序的唯一缺点在于,一旦输入数据中有很多的相同数据,随机化的效果将直接减弱。对于极限情况,即对于n个相同的数排序,随机化快速排序的时间复杂度将毫无疑问的降低到O(n^2)。解决方法是用一种方法进行扫描,使没有交换的情况下主元保留在原位置。 QUICKSORT(A,p,r)
    1 if p<r
    2 then q ←PARTITION(A,p,r)
    3 QUICKSORT(A,p,q-1)
    4 QUICKSORT(A,q+1,r)
    为排序一个完整的数组A,最初的调用是QUICKSORT(A,1,length[A])。
    快速排序算法的关键是PARTITION过程,它对子数组A[p..r]进行就地重排:
    PARTITION(A,p,r)
    1 x←A[r]
    2 i←p-1
    3 for j←p to r-1
    4 do if A[j]≤x
    5 then i←i+1
    6 exchange A[i]←→A[j]
    7 exchange A[i+1]←→A[r]
    8 return i+1 对PARTITION和QUICKSORT所作的改动比较小。在新的划分过程中,我们在真正进行划分之前实现交换:
    (其中PARTITION过程同快速排序伪代码(非随机))
    RANDOMIZED-PARTITION(A,p,r)
    1 i← RANDOM(p,r)
    2 exchange A[r]←→A[i]
    3 return PARTITION(A,p,r)
    新的快速排序过程不再调用PARTITION,而是调用RANDOMIZED-PARTITION。
    RANDOMIZED-QUICKSORT(A,p,r)
    1 if p<r
    2 then q← RANDOMIZED-PARTITION(A,p,r)
    3 RANDOMIZED-QUICKSORT(A,p,q-1)
    4 RANDOMIZED-QUICKSORT(A,q+1,r) 这里为方便起见,我们假设算法Quick_Sort的范围阈值为1(即一直将线性表分解到只剩一个元素),这对该算法复杂性的分析没有本质的影响。
    我们先分析函数partition的性能,该函数对于确定的输入复杂性是确定的。观察该函数,我们发现,对于有n个元素的确定输入L[p..r],该函数运行时间显然为θ(n)。
    最坏情况
    无论适用哪一种方法来选择pivot,由于我们不知道各个元素间的相对大小关系(若知道就已经排好序了),所以我们无法确定pivot的选择对划分造成的影响。因此对各种pivot选择法而言,最坏情况和最好情况都是相同的。
    我们从直觉上可以判断出最坏情况发生在每次划分过程产生的两个区间分别包含n-1个元素和1个元素的时候(设输入的表有n个元素)。下面我们暂时认为该猜测正确,在后文我们再详细证明该猜测。
    对于有n个元素的表L[p..r],由于函数Partition的计算时间为θ(n),所以快速排序在序坏情况下的复杂性有递归式如下:
    T(1)=θ(1),T(n)=T(n-1)+T(1)+θ(n) (1)
    用迭代法可以解出上式的解为T(n)=θ(n2)。
    这个最坏情况运行时间与插入排序是一样的。
    下面我们来证明这种每次划分过程产生的两个区间分别包含n-1个元素和1个元素的情况就是最坏情况。
    设T(n)是过程Quick_Sort作用于规模为n的输入上的最坏情况的时间,则
    T(n)=max(T(q)+T(n-q))+θ(n),其中1≤q≤n-1 (2)
    我们假设对于任何k<n,总有T(k)≤ck,其中c为常数;显然当k=1时是成立的。
    将归纳假设代入(2),得到:
    T(n)≤max(cq2+c(n-q)2)+θ(n)=c*max(q2+(n-q)2)+θ(n)
    因为在[1,n-1]上q2+(n-q)2关于q递减,所以当q=1时q2+(n-q)2有最大值n2-2(n-1)。于是有:
    T(n)≤cn2-2c(n-1)+θ(n)≤cn2
    只要c足够大,上面的第二个小于等于号就可以成立。于是对于所有的n都有T(n)≤cn。
    这样,排序算法的最坏情况运行时间为θ(n2),且最坏情况发生在每次划分过程产生的两个区间分别包含n-1个元素和1个元素的时候。
    时间复杂度为o(n2)。
    最好情况
    如果每次划分过程产生的区间大小都为n/2,则快速排序法运行就快得多了。这时有:
    T(n)=2T(n/2)+θ(n),T(1)=θ(1) (3)
    解得:T(n)=θ(nlogn)
    快速排序法最佳情况下执行过程的递归树如下图所示,图中lgn表示以10为底的对数,而本文中用logn表示以2为底的对数.
    由于快速排序法也是基于比较的排序法,其运行时间为Ω(nlogn),所以如果每次划分过程产生的区间大小都为n/2,则运行时间θ(nlogn)就是最好情况运行时间。
    但是,是否一定要每次平均划分才能达到最好情况呢。要理解这一点就必须理解对称性是如何在描述运行时间的递归式中反映的。我们假设每次划分过程都产生9:1的划分,乍一看该划分很不对称。我们可以得到递归式:
    T(n)=T(n/10)+T(9n/10)+θ(n),T(1)=θ(1) (4)
    请注意树的每一层都有代价n,直到在深度log10n=θ(logn)处达到边界条件,以后各层代价至多为n。递归于深度log10/9n=θ(logn)处结束。这样,快速排序的总时间代价为T(n)=θ(nlogn),从渐进意义上看就和划分是在中间进行的一样。事实上,即使是99:1的划分时间代价也为θ(nlogn)。其原因在于,任何一种按常数比例进行划分所产生的递归树的深度都为θ(nlogn),其中每一层的代价为O(n),因而不管常数比例是什么,总的运行时间都为θ(nlogn),只不过其中隐含的常数因子有所不同。(关于算法复杂性的渐进阶,请参阅算法的复杂性)
    平均情况
    快速排序的平均运行时间为θ(nlogn)。
    我们对平均情况下的性能作直觉上的分析。
    要想对快速排序的平均情况有个较为清楚的概念,我们就要对遇到的各种输入作个假设。通常都假设输入数据的所有排列都是等可能的。后文中我们要讨论这个假设。
    当我们对一个随机的输入数组应用快速排序时,要想在每一层上都有同样的划分是不太可能的。我们所能期望的是某些划分较对称,另一些则很不对称。事实上,我们可以证明,如果选择L[p..r]的第一个元素作为支点元素,Partition所产生的划分80%以上都比9:1更对称,而另20%则比9:1差,这里证明从略。
    平均情况下,Partition产生的划分中既有“好的”,又有“差的”。这时,与Partition执行过程对应的递归树中,好、差划分是随机地分布在树的各层上的。为与我们的直觉相一致,假设好、差划分交替出现在树的各层上,且好的划分是最佳情况划分,而差的划分是最坏情况下的划分。在根节点处,划分的代价为n,划分出来的两个子表的大小为n-1和1,即最坏情况。在根的下一层,大小为n-1的子表按最佳情况划分成大小各为(n-1)/2的两个子表。这儿我们假设含1个元素的子表的边界条件代价为1。
    在一个差的划分后接一个好的划分后,产生出三个子表,大小各为1,(n-1)/2和(n-1)/2,代价共为2n-1=θ(n)。一层划分就产生出大小为(n-1)/2+1和(n-1)/2的两个子表,代价为n=θ(n)。这种划分差不多是完全对称的,比9:1的划分要好。从直觉上看,差的划分的代价θ(n)可被吸收到好的划分的代价θ(n)中去,结果是一个好的划分。这样,当好、差划分交替分布划分都是好的一样:仍是θ(nlogn),但θ记号中隐含的常数因子要略大一些。关于平均情况的严格分析将在后文给出。
    在前文从直觉上探讨快速排序的平均性态过程中,我们已假定输入数据的所有排列都是等可能的。如果输入的分布满足这个假设时,快速排序是对足够大的输入的理想选择。但在实际应用中,这个假设就不会总是成立。
    解决的方法是,利用随机化策略,能够克服分布的等可能性假设所带来的问题。
    一种随机化策略是:与对输入的分布作“假设”不同的是对输入的分布作“规定”。具体地说,在排序输入的线性表前,对其元素加以随机排列,以强制的方法使每种排列满足等可能性。事实上,我们可以找到一个能在O(n)时间内对含n个元素的数组加以随机排列的算法。这种修改不改变算法的最坏情况运行时间,但它却使得运行时间能够独立于输入数据已排序的情况。
    另一种随机化策略是:利用前文介绍的选择支点元素pivot的第四种方法,即随机地在L[p..r]中选择一个元素作为支点元素pivot。实际应用中通常采用这种方法。
    快速排序的随机化版本有一个和其他随机化算法一样的有趣性质:没有一个特别的输入会导致最坏情况性态。这种算法的最坏情况性态是由随机数产生器决定的。你即使有意给出一个坏的输入也没用,因为随机化排列会使得输入数据的次序对算法不产生影响。只有在随机数产生器给出了一个很不巧的排列时,随机化算法的最坏情况性态才会出现。事实上可以证明几乎所有的排列都可使快速排序接近平均情况性态,只有非常少的几个排列才会导致算法的近最坏情况性态。
    一般来说,当一个算法可按多条路子做下去,但又很难决定哪一条保证是好的选择时,随机化策略是很有用的。如果大部分选择都是好的,则随机地选一个就行了。通常,一个算法在其执行过程中要做很多选择。如果一个好的选择的获益大于坏的选择的代价,那么随机地做一个选择就能得到一个很有效的算法。我们在前文已经了解到,对快速排序来说,一组好坏相杂的划分仍能产生很好的运行时间 。因此我们可以认为该算法的随机化版本也能具有较好的性态。

    踩0 评论0
  • 回答了问题 2019-07-17

    北京大学工学院的课程设置

    第一学年 不分专业
    微积分(一)、微积分(二)、线性代数与几何、概率与数理统计、计算方法、普通物理学及实验、理论力学、普通化学、热动力学、现代工学通论
    第二学年以后必修课 空气动力学、飞行器结构力学、航空航天概论、机械设计基础、电路与电子学、自动控制原理、工程热力学、飞行器总体设计、飞行器结构设计、理论力学、材料力学、航空航天工程专业限选课(至少21学分)、常微分方程、 工程数学、电磁学(普通物理)、近代物理(普通物理)、普通物理实验(B)(一)等
    选修课 各专业均有
    微机原理、固体力学进展、流体力学进展、工程材料概论、生物医学工程概论、系统工程概论、系统与控制引论、智能优化算法引论、生物固体力学、生物流体力学、计算流体力学、粘性流体力学、塑性力学、振动理论、断裂力学、弹性板理论、弹性力学变分原理、气体力学、传热传质引论、工业空气动力学、工程塑性力学、工程流变学、经典力学中的数学方法、现代数学引论、力学史、土力学与地基、专业英语、有限元法、计算几何、工程CAD、概率与统计、自动控制原理、计算机图像处理、医学信号与医学图像处理、生物医学传感器、生物信息学算法导论、油气田开发、提高采收率、测井理论与解释、油田化学、地震解释、钻井工程、地面储运工程、石油地质、采油工艺、试井理论、石油仪器仪表、燃烧物理化学入门、燃烧技术、生态环境概论、大气空气动力学、环境污染化学、系统生态学、环境与资源经济学、水文水资源、地下水动力学、非饱和带水文学、污染物运移与治理等

    踩0 评论0
正在加载, 请稍后...
滑动查看更多