1. 程式人生 > >N-ary Tree n叉樹學習

N-ary Tree n叉樹學習

N 叉樹 定義


  • 二叉樹是一顆以根節點開始,每個節含有不超過2個子節點的樹。N 叉樹,即每個節點不超過N個子節點的樹。
  • 一顆三叉樹:

在這裡插入圖片描述
字首樹,又稱為字典樹,就是一個常用的N叉樹。


遍歷

N-ary Tree Preorder Traversal:

給定一個 N 叉樹,返回其節點值的前序遍歷。

例如,給定一個 3叉樹 :

在這裡插入圖片描述
返回其前序遍歷: [1,3,5,6,2,4]。

說明: 遞迴法很簡單,你可以使用迭代法完成此題嗎?

  • 方法一:遞迴法:
class Solution {
public:
	vector<int> preorder(Node* root){
		if(root != nullptr)
		{
			res.push_back(root->val);
			for(auto n :  root->children)
				preorder(n);
		}
		return res;
	}
private:
	vector<int> res;
};
  • 方法二:迭代法: 用棧
/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
public:
    vector<int> preorder(Node* root) {
        if(root == nullptr)
            return res;
        
        s_node.push(root);
        while(!s_node.empty())
        {
            Node* temp = s_node.top();
            res.push_back(temp->val);
            s_node.pop();
            for(int i = temp->children.size() - 1; i>=0; i--)
            {
                s_node.push(temp->children[i]);
            }
        }
        return res;
    }

private:
    vector<int> res;
    stack<Node*> s_node;
    
};

N-ary Tree Postorder Traversal

在這裡插入圖片描述


  • 方法 1 :遞迴法
class Solution {
public:
    vector<int> postorder(Node* root) {
        if(root != nullptr){
            for(auto n : root->children)
            {
                postorder(n);             
            }
            res.push_back(root->val);  
        }
        return res;
    }
private:
    vector<int> res;

};

方法二:迭代 :棧

  • 我們同樣使用迭代先把根節點放入棧中,然後把它的孩子依次放入,這樣我們下次遍歷獲得的就是它的最後的節點,每層都是如此。我們每層都是根->右孩子->其餘孩子的遍歷方式,所以最後需要加一個翻轉即可得到後序遍歷。
/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
public:
    vector<int> postorder(Node* root) {
        if(root)
        {
            s_node.push(root);
            while(!s_node.empty())
            {
                Node* temp = s_node.top();
                s_node.pop();
                res.push_back(temp->val);             
                for(auto x : temp->children)
                {
                    s_node.push(x);
                }
            }          
            int size = res.size();        
            for(int i=0; i < size/2; i++)
            {
                int buf = res[i];
                res[i]  = res[size - i - 1];
                res[size - i - 1] = buf;
            }
        }
        return res;
    }
private:
    vector<int> res;
    stack<Node*> s_node;
};

N叉樹的層序遍歷

在這裡插入圖片描述

  • 思路, 首先想到用佇列;
  • 每一層的個數得知道吧?
  • 每一層分別遍歷不就可以了
  • 一層一層的進入佇列這是關鍵,不然分界點怎麼辦,於是先求首層的(root)的大小,遍歷此層並出佇列,加入結果中,然後將此層的結點放進佇列中; 第二次求 第二層的大小,然後遍歷並出佇列,然後將第三層結點放進佇列!!!
/*
// Definition for a Node.
class Node {
public:
    int val = NULL;
    vector<Node*> children;

    Node() {}

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        if(root)
        {
            q_node.push(root);     
            while(!q_node.empty())
            {
                int size = q_node.size();
                vector<int> r(size);
                for(int i = 0; i < size; i++)
                {
                     Node* temp = q_node.front();
                     q_node.pop();
                     r[i] = temp->val;
                     for(auto x : temp->children)
                     {
                         q_node.push(x);
                     }
                } 
                res.push_back(r);
            }
            
        }
        return res;
    }
    
private:
    vector<vector<int>> res;
    queue<Node*> q_node;
};

Maximum Depth of N-ary Tree

在這裡插入圖片描述


  • 遞迴!!!

對於二叉樹來說求一棵樹的最大深度!

int maxDepth(ThreeNode* node)
{
	if(node == nullptr)
		return  0 ;
	return max(maxDepth(node->left), maxDepth(node->right)) + 1;
}
  • 擴充套件到多叉樹,所以是對所有孩子結點進行判斷!
/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
public:
    int maxDepth(Node* root) {
        if(root == nullptr)
            return 0;
        int dep = 0;
        for(auto x : root->children)
            dep = max(dep, maxDepth(x));
        return dep+1;
    }
};

下面的方法可能更能懂,root 不為空 則 dep 至少 為 1,有孩子則深度 加 +1.

class Solution {
public:
    int maxDepth(Node* root) {
        if(root == nullptr)
            return 0;
        int dep = 1;
        for(auto x : root->children)
            dep = max(dep, maxDepth(x) + 1);
        return dep;
    }
};