C++面试总结之算法(二):树

1. 平衡二叉树(AVL)

https://www.cnblogs.com/suimeng/p/4560056.html 

平衡因子:左子树的高度减去右子树的高度。由平衡二叉树的定义可知,平衡因子的取值只可能为0,1,-1.分别对应着左右子树等高,左子树比较高,右子树比较高。

AVL树的插入时的失衡与调整:平衡二叉树的失衡调整主要是通过旋转最小失衡子树来实现的。

2. 红黑树、平衡二叉树、B树的区别

https://blog.csdn.net/v_july_v/article/details/6530142

B树:多叉平衡查找树(降低IO读写操作次数)

3. 求二叉树的最大距离(即相距最远的两个叶子节点,动态规划)

https://my.oschina.net/wizardpisces/blog/116425

计算一个二叉树的最大距离有两个情况:

情况A: 路径经过左子树的最深节点,通过根节点,再到右子树的最深节点。

情况B: 路径不穿过根节点,而是左子树或右子树的最大距离路径,取其大者。

#include <iostream>

using namespace std;

struct NODE{
    NODE *pLeft;
    NODE *pRight;
};

struct RESULT{
    int nMaxDistance;
    int nMaxDepth;
};

RESULT GetMaxDistance(NODE* root) {
    if (!root){
        RESULT empty = { 0, -1 }; // nMaxDepth=-1,后续+1达到平衡 
        return empty;
    }

    RESULT lhs = GetMaxDistance(root->pLeft);
    RESULT rhs = GetMaxDistance(root->pRight);

    RESULT result;
    result.nMaxDepth = max(lhs.nMaxDepth + 1, rhs.nMaxDepth + 1);
    result.nMaxDistance = max(max(lhs.nMaxDistance, rhs.nMaxDistance), lhs.nMaxDepth + rhs.nMaxDepth + 2);

    return result;
}

为了减少 NULL 的条件测试,进入函数时,如果节点为 NULL,会传回一个 empty 变量。比较奇怪的是 empty.nMaxDepth = -1,目的是让调用方 +1 后,把当前的不存在的 (NULL) 子树当成最大深度为 0。计算 result 的代码很清楚;nMaxDepth 就是左子树和右子树的深度加1;nMaxDistance 则取 A 和 B 情况的最大值。

void Link( NODE* nodes, int parent, int left, int right) {
    if (left != -1)
        nodes[parent].pLeft = &nodes[left]; 

    if (right != -1)
        nodes[parent].pRight = &nodes[right];
}

void main(){
    NODE test1[9] = { 0 };

    Link(test1, 0, 1, 2);
    Link(test1, 1, 3, 4);
    Link(test1, 2, 5, 6);
    Link(test1, 3, 7, -1);
    Link(test1, 5, -1, 8);
    cout << "test1: " << GetMaximumDistance(&test1[0]).nMaxDistance << endl;
}

4.求二叉树的宽度,先简介思路再写代码。(按层遍历)

把二叉树中每层的节点依次放入一个队列中。设置一个变量width用于存储树的宽度。每一层的节点入队时计算该层节点的数目,如果该层次节点的数目大于width的值,那么把该层次节点的数目赋给width。如此,对二叉树按层遍历一遍之后width中保存的就是该二叉树的宽度。

int WidthOfTheTree(Node* pRoot) {  
    if(pRoot==NULL)  
        return 0;  

    queue<Node*> MyQueue2;  
    MyQueue2.push(pRoot);  
    int width=1, curwidth=1, nextwidth=0;  

    while(!MyQueue2.empty()) {  
        while(curwidth!=0) {  
            Node* pTmp=MyQueue2.front();  
            MyQueue2.pop();  
            curwidth--;  
            if(pTmp->pLeft!=NULL) {  
                MyQueue2.push(pTmp->pLeft);  
                nextwidth++;  
            }  
            if (pTmp->pRight!=NULL) {  
                MyQueue2.push(pTmp->pRight); 
                nextwidth++;   
            }
        }  

        if(nextwidth > width)  
            Width = nextwidth;  
        Curwidth = nextwidth;  
        Nextwidth = 0;  
    }  

    return width;  
} 

5.求二叉树的深度,先简介思路再写代码。

int Deep(TreeNode *pRoot){  
    if(pRoot==NULL)  
        return 0;  

    int DL=DeepthOfTheTree(pRoot->pLeft);  
    int DR=DeepthOfTheTree(pRoot->pRight);  
    int Depth=DL>DR? DL:DR;  

    return Depth+1;  
}

猜你喜欢

转载自blog.csdn.net/lxin_liu/article/details/89307365