2022暑期复习-Day8

Posted Booksort

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022暑期复习-Day8相关的知识,希望对你有一定的参考价值。

目录

选择题

Q1 当一个类的某个函数被说明为 virtual ,则在该类的所有派生类中的同原型函数( )。

A: 只有被重新说明时才识虚函数
B: 只有被重新说明为virtual时才是虚函数
C: 都不是虚函数
D: 都是虚函数

这是多态中的一种特例,虽然在派生类中没有显示说明改函数的virtual的特性,但是派生类会继承基类的成员函数,这样virtual的作用域也被带到了派生类中,所以派生类中的同名函数也具有virtual的特性

答案:D

Q2 关于 C++ 类中 static 成员和对象成员的说法正确的是( )。

A: static 成员变量在对象构造时生成
B: static 成员函数在普通成员函数中无法调用
C: 虚成员函数不可能是static 成员函数
D: static 成员函数不能访问static 成员变量

static 成员变量的内存既不是在声明类时分配,也不是在创建对象时分配,而是在(类外)初始化时分配。反过来说,没有在类外初始化的 static 成员变量不能使用。

static成员函数不被对象所独有,所有对象都能调用static函数。

虚函数是不能使用static关键字,主要原因是,虚函数调用需要this指针,而static函数不需要。
从编译的角度来看,static成员函数是在编译时,静态绑定了的,而虚函数是在运行时,动态绑定。

答案:C

Q3 C++ 将父类的析构函数定义为虚函数,下列正确的是( )。

A: 释放父类指针时能正确释放子类对象
B: 释放子类指针时能正确释放父类对象
C: 这样做是错误的
D: 以上全错

主要用途,在释放父类指针时,如果父类指针指向了一个子类对象,那么可以调用子类的析构继而调用父类的析构,删除这个对象,防止内存泄漏问题。

答案:A

Q4 假设 A 为抽象类,下列声明( )是正确的。

A: int fun(A);
B: A Obj;
C: A fun(int);
D: A *p;

有纯虚函数作为成员函数的类叫做抽象类。
抽象类是为了表述一个无法描述事物而留下的接口,这样是也导致未重写纯虚函数的类无法实例化
无法实例化,也意味着不能构造,所以涉及到创建变量的使用都是错误的,而指针不会,指针只是一个指定大小的地址,并不设计资源创建

答案:D

Q5 下面程序的输出结果是()

class A

public:
    void foo()
    
        printf("1");
     
    virtual void fun()
    
        printf("2");
    
;
class B : public A

public:
    void foo()
    
        printf("3");
     
    void fun()
    
        printf("4");
    
;
int testmain(void)



A a;
B b;
A* p = &a;
p->foo();
p->fun();
p = &b;
p->foo();
p->fun();
A* ptr = (A*)&b;
ptr->foo();
ptr->fun();
return 0;

A: 121434
B: 121414
C: 121232
D: 123434

看看指针和函数调用。

基类指针指向基类对象,不涉及多态,调用基类的函数
输出12

基类指针直指向派生类对象,涉及多态,考虑 虚基表
foo函数涉及 隐藏 ,基类指针调用,调用的会是基类的函数,fun函数是多态,调用派生类的函数。输出14

基类指针指向一个派生类强转成基类的对象
强转类型就涉及到切片原理,切片还是切割基类,调用基类的foo函数,同时调用fun函数也涉及到多态的性质。输出14
只有在派生类的作用域中调用foo函数才会输出 3

答案:B

编程题

Q6


遍历一颗二叉搜索树,最重要的是中序遍历,题目要求头指针指向最小的节点,那就是中序遍历的第一个节点。

同时,中序遍历,将所有节点入栈,使用prev指针和一个cur指针去遍历栈中的元素,建立双向链表。

/*
// Definition for a Node.
class Node 
public:
    int val;
    Node* left;
    Node* right;

    Node() 

    Node(int _val) 
        val = _val;
        left = NULL;
        right = NULL;
    

    Node(int _val, Node* _left, Node* _right) 
        val = _val;
        left = _left;
        right = _right;
    
;
*/
class Solution 
public:
    Node* treeToDoublyList(Node* root) 
        //中序遍历
        Node* Head=nullptr;
        stack<Node*> st;
        Node* cur = root;
        bool flag = false;
        Node* prev=nullptr;
        while(!st.empty()||cur)
        
            if(cur)
            
                st.push(cur);
                cur=cur->left;
            
            //主要关注栈中的元素
            else
            
                if(flag==false)
                
                    flag = true;
                    Head = st.top();
                
                cur = st.top();
                st.pop();

                cur->left = prev;
                if(prev!=nullptr)
                
                    prev->right = cur;
                
                
                if(prev == nullptr)
                    prev = cur;
                else 
                    prev = prev->right;

                cur = cur->right;
                if(cur == nullptr)//处理最后一个节点和头结点
                
                    prev->right = Head;
                    Head->left = prev;
                
            
        
        return Head;
    
;

Q7

最简单的办法就是找到根节点到目标节点的路径,然后两条路径依次遍历,
先保证长度一致,然后再一起遍历节点,最后可以得到一个一样的节点,就算最近公共祖先,最远公共祖先就算整棵树的根节点。

使用后续遍历,完成深度优先搜素,可以找到节点,并记录路径。

class Solution 
public:
    void find_path(stack<TreeNode*>& st,TreeNode* root, TreeNode* p)
    
        TreeNode* cur = root;
        TreeNode* prev = root;
        st.push(cur);
        while(!st.empty())
        
            cur = st.top();
            if(cur->left && cur->left!=prev && cur->right!=prev)
            
                st.push(cur->left);
            
            else if(cur->right&&cur->right!=prev)
            
                st.push(cur->right);
            
            else
            
                prev = cur;
                if(cur==p)
                
                    break;
                
                st.pop();
            
        
    
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
        stack<TreeNode*> st1;
        stack<TreeNode*> st2;
        //后序遍历完成深度优先搜索路径
        find_path(st1, root, p);
        find_path(st2, root, q);
        while(st1.size()>st2.size())
        
            st1.pop();
        
        while(st1.size()<st2.size())
        
            st2.pop();
        
        while(st1.top()!=st2.top())
        
            st1.pop();
            st2.pop();
        

        return st1.top();
    
;

以上是关于2022暑期复习-Day8的主要内容,如果未能解决你的问题,请参考以下文章

编写代码最应该做好的事情是什么?(备战2022春招或暑期实习,每天进步一点点,打卡100天,Day8)

编写代码最应该做好的事情是什么?(备战2022春招或暑期实习,每天进步一点点,打卡100天,Day8)

2022暑期复习-Day4

2022暑期复习-Day6

2022暑期复习-Day3

2022暑期复习-Day3