zoukankan      html  css  js  c++  java
  • 专项训练错题整理-nowcoder-算法

    一、排序

    1.快速排序在下列哪种情况下最易发挥其长处?

    答案是:

    被排序的数据完全无序。

     在数据基本有序的情况下,会退化为冒泡排序,复杂度会退化为O(n^2)。

    [因为,如果是基本有序的话, 那么每次选取pivot,那么就会将序列分为两个长度相差很大的序列,比如1和n-1个,这样复杂度就会变成O(n^2),就是冒泡排序了]

    [最好的情况就是分称平均得两份,那么复杂度是O(nlogn)]。

     为什么呢?

     //快速排序的思想都忘了,到底是i和j互换吗?代码实现也不怎么会写,是递归调用吗?(是递归调用)

     转自:https://www.cnblogs.com/surgewong/p/3381438.html

     选取两个指向,一个是i从前向后,一个是j从后往前,i呢是越过所有小于pivot的元素(遇到等于pivot的不停),j呢越过所有不小于pivot的元素(对于等于pivot的元素不停,对它们i已经负责交换了,j就不必负责相等值得交换),通过这样可以消除逆序,而且分为更短的序列,序列之间不会再进行比较,减少了比较次数。

     ②还有非常重要的一点就是:快速排序使用递归调用需要栈,如果是序列平均分的话,那么递归最大深度就是O(logn),如果是按照非常不平均1和n-1那么最大调用深度就是O(n)。

    :快速排序在排序过程中是根据基数值来进行比较,并不是进行相邻元素的比较,所以是一种不稳定的排序。

    #include <iostream>
    
    using namespace std;
    int a[6]={2 ,4 ,0 ,7 ,1 ,6};
    void qs(int f,int t){
        int pivot=f;
        int i=f,j=t;
        while(i<=j){//那么在这又产生了一个疑问,到底快排是稳定还是不稳定的呢?
            while(j>a[pivot]&&j>i){
                j--;
            }
            while(i<=a[pivot]&&i<j){
                i++;
            }
    
        }
    }
    
    int main(){
         //手动实现快排,加深印象。
    
         //int pivot=0;
         qs(0,5);
         return 0;
    }
    My laji Code

     //这个代码太厉害了!

    #include <stdio.h>
    
    #define MAX_NUM 80
    
    void quicksort(int* a, int p,int q)
    {
        int i = p;
        int j = q;
        int temp = a[p];
    
        while(i < j)//不用=,那样自己和自己交换也没意思,应该也不会产生这样吧。
        {
            // 越过不小于基准值的数据
            while( a[j] >= temp && j > i ) j--;
    
            if( j > i )
            {
                a[i] = a[j];//是这样赋值,而不是交换。
                i++;//赋值完了之后,忘后移动一个。
    
                // 越过小于基准值的数据
                while(a[i] <= temp && i < j )  i++;//这个时候i再往前走。
                if( i < j )
                {
                    a[j] = a[i];
                    j--;//赋值完了之后,往前移动一个。
                }
            }
        }
        a[i] = temp;//这里i被赋值为temp。
    
        for(int k = p; k <= q;k++)//这个主要就是打印一下序列。
        {
            if( k == i )
            {
                printf("(%d) ",a[k]);
                continue;
            }
            printf("%d ",a[k]);
        }
        printf("
    ");
    
        if( p < (i-1)) quicksort(a,p,i-1);//递归调用。
        if((j+1) < q ) quicksort(a,j+1,q);
    }
    
    int main(int argc, char* argv[])
    {
        int a[MAX_NUM];
        int n;
    
        printf("Input total numbers: ");
        scanf("%d",&n);
    
        if( n > MAX_NUM ) n = MAX_NUM;
    
        for(int i = 0; i < n;i++)
        {
            scanf("%d",&a[i]);
        }
    
        printf("Divide sequence:
    ");
        quicksort(a,0,n-1);
    
        printf("The sorted result:
    ");
        for(int i = 0; i < n;i++)
        {
            printf("%d ",a[i]);
        }
        printf("
    ");
    
        return 0;
    }

    运行结果:

    2.下面的排序方法中,关键字比较次数与记录的初始排列无关的是_

    无关是什么意思呢?就是在最好最坏平均情况下它的复杂度都不变的。

    那么从图中可以看出,是直接选择排序,堆排序,归并排序与初始状态无关。//这个图要多背几遍啊!

     3.个数约为 50k 的数列需要从小到大排序, 数列特征是基本逆序 (多数数字从大到小,个别乱序) ,以下哪种排序算法在事先不了解数列特征的情况下性能大概率最优(不考虑空间限制)___.

     堆排序。 

  • 相关阅读:
    最终一致性解决实例
    分布式事务一致性方案
    分布式事务
    OSX
    JAVA
    Eclipse
    Activiti
    CentOS
    用Visual Studio 2015 编写 MASM 汇编程序(二)从头开发一个Win32汇编程序
    Oracle
  • 原文地址:https://www.cnblogs.com/BlueBlueSea/p/9614902.html
Copyright © 2011-2022 走看看