面试题-4-18

  1. c++ vector的内存优化方法。

    a. 背景知识:vector的内存空间只能增大,不能减小。并且大小是2的幂次,数据连续排放。如果不够了会重新开一片连续的内存,将原来的拷贝过去。

    b. 所有的内存空间只在析构的时候才会被释放。用swap函数是可以做到释放内存的。

    c. vector采用的技术是预分配技术,分配的时候会比需要的大一些,这样不需要频繁分配和释放。

    d.vector还有一个复用技术,vector元素用完之后不会释放内存,而是做一个标记。这样就避免了频繁的内存分配和释放操作。

  2. 介绍一下堆排序:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N  = 1e5 + 5;
    
    int a[N];
    int n;
    
    void adjust(int mx_n, int nd){
        int lson=(nd<<1)+1;
        int rson=(nd<<1)+2;
    
        int mx=nd;
        if(lson<mx_n&&a[lson]>a[nd]){
            mx=lson;
        }
    
        if(rson<mx_n&&a[rson]>a[nd]){
            mx=rson;
        }
    
        if(mx!=nd){
            swap(a[nd], a[mx]);
            adjust(mx_n, mx);
        }
    }
    
    void heap_sort(){
        for(int i=n/2-1;i>=0;--i){
            adjust(n, i);
        }
    
        for(int i=n-1;i>=0;--i){
            swap(a[0],a[i]);
            adjust(i, 0);
        }
    }
    
    int main(){
        cin >> n;
        for(int i=0;i<n;++i){
            cin >> a[i];
        }
        heap_sort();
        for(int i=0;i<n;++i)cout<<a[i]<<" ";
        cout<<endl;
        return 0;
    }
    
  3. 介绍一下堆插入和删除的算法。

    简单,插入就放入末尾,然后一直往上走,在这个过程中只比较和父亲的大小,大就交换上去。

    删除,先把堆顶与末尾交换。然后一直往下走,找比它大的交换(需要比较两个儿子)。

  4. 虚函数原理:

    每个包含虚函数的类都有自己的虚函数表(指针数组)。这是一个在编译时确定的静态数组。虚函数表包括了指向每个虚函数的函数指针。其次,在基类中还定义了一个隐藏指针:vptr。这个指针是在类实例创建时自动设置的,用途是指向类的虚函数表。与this指针不一样,this指针是一个函数参数,达到的是自引用的目的。vptr被设置为指向类的虚函数表。实例化的时候会被设置为指向虚函数指针数组。具体看:C++ | 虚函数表及虚函数执行原理详解 - 知乎 (zhihu.com)

  5. 手写一下快速排序

    #include <bits/stdc++.h>
    
    using namespace std;
    
    using LL = long long;
    
    const int N  = 1e5 + 5;
    
    const int INF = 2147483647;
    
    int a[N];
    int n;
    
    
    void q_sort(int l, int r){
        int anchor=a[l+(r-l)/2];
        int i=l, j=r;
        while(i<=j){
            while(a[i]<=anchor)++i;
            while(a[j]>=anchor)--j;
            if(i<=j){
                swap(a[i],a[j]);
                ++i;
                --j;
            }
        }
    
        if(l<j) q_sort(l, j);
        if(i<r) q_sort(i, r);
    }
    
    int main(){
        cin >> n;
        for(int i=0;i<n;++i){
            cin >> a[i];
        }
        q_sort(0,n-1);
        for(int i=0;i<n;++i)cout<<a[i]<<" ";
        cout<<endl;
        return 0;
    }
    

    写一个快排的优化(三路快排):

    #include <bits/stdc++.h>
    
    using namespace std;
    
    using LL = long long;
    
    const int N  = 1e5 + 5;
    
    const int INF = 2147483647;
    
    int a[N];
    int n;
    
    void q_sort(int l, int r){ // [l, lt) < a[l], [lt, i] == a[l], (gt, r] > a[l]
        if(l>r)return;
    
        int anchor=a[l];
        int lt=l, i=l+1,gt=r;
        while(i<=gt){
            if(a[i]<anchor){
                swap(a[lt++], a[i++]);
            }else if(a[i]>anchor){
                swap(a[gt--], a[i++]);
            }else{
                i++;
            }
        }
    
        q_sort(l, lt-1);
        q_sort(gt+1, r);
    }
    
    int main(){
        cin >> n;
        for(int i=0;i<n;++i){
            cin >> a[i];
        }
        q_sort(0,n-1);
        for(int i=0;i<n;++i)cout<<a[i]<<" ";
        cout<<endl;
        return 0;
    }
    
posted @ 2023-04-18 21:16  John_Ran  阅读(19)  评论(0编辑  收藏  举报