N-ary Tree n叉樹學習
阿新 • • 發佈:2018-11-26
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;
}
};