zoukankan      html  css  js  c++  java
  • 深信服笔试

    1 struct还有这种神奇的初始化方式:

    struct node{
        int v1;
        int v2;
    }t{1};
    //t.v1 = 1
    tt{1, 2};
    //tt.v1 = 1  tt.v2 = 2

    2 static声明的局部变量 默认初始化

    static int sss;

    3 堆

    一个初始堆是一个完全二叉树

    举例说明:

    给定一个整形数组a[]={16,7,3,20,17,8},对其进行堆排序。

    首先构建一个二叉树:

    然后我们希望调整出一个大顶堆

    则从最后一个非叶结点开始调整,过程如下:

    找到 节点、左孩子、右孩子 三者中的最大值,放到节点位置上

    继续调整该节点父节点之间的位置关系:

    后头发现,16 与 17关系不满足,继续自上而下调整它

    这样就得到了初始堆 而且还是个 大顶堆

    即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。

    下面开始排序了!

    20  17  8  7  16  3

    把第一个和最后一个元素交换       3    17    8    7  16  20     得到最大元素 20   因为之前已经保证了 堆顶元素最大

    去掉最后一个元素 & 调整 得到   :   17  10  8    7    3     

    把第一个和最后一个元素交换:    3  10  8  7  17        得到最大元素 17   因为之前已经保证了 堆顶元素最大 

    去掉最后一个元素 & 调整 得到   :  10  7  3  8

    把第一个和最后一个元素交换:    8    7  3  10           得到最大元素 10   因为之前已经保证了 堆顶元素最大 

    去掉最后一个元素 & 调整 得到   :  8  7  3  

    把第一个和最后一个元素交换:    3  7  8              得到最大元素 8     因为之前已经保证了 堆顶元素最大 

    去掉最后一个元素 & 调整 得到   :   7   3          

    把第一个和最后一个元素交换:    3  7                得到最大元素 7     因为之前已经保证了 堆顶元素最大 

    去掉最后一个元素 & 调整 得到   :   3

    把第一个和最后一个元素交换:   3                得到最大元素 3     因为之前已经保证了 堆顶元素最大 

    去掉最后一个元素 & 调整 得到   :  空                END : 结束排序

    实现了:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define LS(x) x << 1
    #define RS(x) x << 1 | 1
    using namespace std;
    
    template<class T>
    void updateMaxHeap(T *a, int i, int n)
    {
        int left = LS(i), right = RS(i), largest;
        if(left > n) return ;
        largest = left;
        if(right <= n && a[right] > a[largest]){
            largest = right;
        }
        if(a[i] < a[largest]){  // 孩子 大于 父节点 需要调整
            swap(a[i], a[largest]);
            updateMaxHeap(a, largest, n);
        }//如果根节点最大 那么不用继续调整下去了
    }
    
    template<class T>
    void create_max_heap(T *a, int n)
    {
        // 1...n/2 是树中所有非叶子结点 只需要调整非叶子节点即可
        // 倒着调整建堆:这点很重要!
        for(int i = n/2; i >= 1; i --){
            updateMaxHeap(a, i, n);
        }
    }
    
    template<class T>
    void heap_sort(T *a, int n)
    {
    
        create_max_heap(a, n);
        cout<<"Max Heap: "<<endl;
        for(int i = 1; i <= n; i ++)
            cout<<a[i]<<" ";
        for(int i = n; i >= 2; i --){
            swap(a[i], a[1]);
            updateMaxHeap(a, 1, i - 1);
        }
        cout<<"Sort: "<<endl;
        for(int i = 1; i <= n; i ++)
            cout<<a[i]<<" ";
    }
    
    double nums[100];
    int main()
    {
    
        int n;
        cin>>n;
        for(int i = 1; i <= n; i ++)
            cin>>nums[i];
        heap_sort(nums, n);
        return 0;
    }
    //1 5 4 2 3 6

     最后时间复杂度:

      建堆O(n*log2n)

      筛选法调整堆O(log2n)

      总共循环了n-1次调整函数,所以调整堆时间复杂度为O(n*log2n)

      熟悉了堆排序的过程后,可以发现堆排序不存在最佳情况,待排序序列是有序或者逆序时,并不对应于堆排序的最佳或最坏情况。且在最坏情况下时间复杂度也是O(n*log2n)。此外堆排序是不稳定的原地排序算法。

  • 相关阅读:
    常用的正则表达式
    vue多页面应用
    webpack + jquery + bootstrap 环境配置
    Goroutine的几个例子
    设置css通用字体
    简单的gulpfile.js参数配置
    1:时间戳转换成年月日函数,2:url截取参数方法,3:弹窗自定义方法 4:点击按钮加入购物车
    github上比较全的知识
    秒杀倒计时
    正则校验手机号码并获取手机验证码倒计时的实例
  • 原文地址:https://www.cnblogs.com/luntai/p/6601643.html
Copyright © 2011-2022 走看看