94. Le pré-commande d'arbre binaire
Idée: penser algorithme récursif classique, mais utiliser les offres de solutions officielles trois solutions. Le premier est le plus facile à comprendre, récursion, le second, la pile et l'itération est complète et traversal renvoie les données, le troisième, avec un arbre spécial complet, de cette façon je me sens pas besoin d'apprendre.
solution récursive:
Code C
typedef struct TreeNode {
int val;
struct TreeNode* left;
struct TreeNode* right;
}TreeNode;
//get树的节点数
int getSize(struct TreeNode* root)
{
if (!root)
return 0;
return getSize(root->left) + getSize(root->right) + 1;
}
//中序遍历树,并将数据读入堆上分配的内存中
void inorderTree(struct TreeNode* root, int* res)
{
//静态变量具有记忆功能
static int index = 0;
if (!root)
return;
inorderTree(root->left, res);
res[index++] = root->val;
inorderTree(root->right, res);
}
//主体函数,上面2个函数是辅助函数
int* inorderTraversal(struct TreeNode* root, int* returnSize) {
*returnSize = getSize(root);
int* res = (int*)malloc(sizeof(int) * *returnSize);
if (*returnSize == 0)
{
return res;
}
inorderTree(root, res);
return res;
}
c ++ code
class Solution {
public:
vector<int> res;
vector<int> inorderTraversal(TreeNode* root) {
if (!root)
return res;
inorderTraversal(root->left);
res.push_back(root->val);
inorderTraversal(root->right);
return res;
}
};
144. L'arbre binaire pré-commande traversal
Idées:
1. algorithme récursif, concis, facile à comprendre, sans aucune explication.
2. algorithme itératif, basé sur des observations d'un algorithme récursif est dérivé, le code des notes détaillées pour le résumé.
algorithme récursif:
Code C
typedef struct TreeNode {
int val;
struct TreeNode* left;
struct TreeNode* right;
}TreeNode;
int getSize(struct TreeNode* root)
{
if (!root) return 0;
return getSize(root->left) + getSize(root->right) + 1;
}
void preorder(struct TreeNode* root, int* res)
{
static int index = 0;
if (!res || !root) return;
res[index++] = root->val;
preorder(root->left, res);
preorder(root->right, res);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
*returnSize = getSize(root);
int* res = (int*)malloc(sizeof(int) * (*returnSize));
if (*returnSize == 0) return res;
//递归的先序遍历tree,并依次访问节点。
preorder(root, res);
return res;
}
c ++ code
class Solution {
public:
vector<int> res;
vector<int> preorderTraversal(TreeNode* root) {
if(!root)
return res;
res.push_back(root->val);
//以下为递归调用,任何一次递归调用执行具有实质效果的代码都是上面的代码,这就如同迭代
//任何一次迭代都将执行相同形式的代码,尾递归形式是最好转为迭代的。
preorderTraversal(root->left);
preorderTraversal(root->right);
return res;
}
};
algorithme 1 itératifs:
Malheureusement, la forme itérative bien que très commun et facile à comprendre , mais pas dans l' ordre, après.
Code C (quelle interface doit être pratique pour écrire ... eh bien, ne pas écrire C)
Le code C de
class Solution {
public:
vector<int> res;
vector<int> preorderTraversal(TreeNode* root) {
stack<const TreeNode*> S; //维护一个临时的辅助栈,元素为指向节点的指针,由于我们不修改节点数据设定底层const
if (root) S.push(root); //根节点存在,入栈
while (!S.empty()) //栈非空,往返循环
{
//以代码作用为,访问局部root节点,在依次访问左孩子,右孩子节点,此为先序遍历
//若孩子节点不存在,即为空,没有任何实质操作,我们用if限制这种特殊情况
auto t = S.top();
vist(t, res);
S.pop();
if (t->right) S.push(t->right);
if (t->left) S.push(t->left);
}
return res;
}
//对节点进行访问,依据题目不同要求可做修改,该题目要求为读取数据
inline void vist(const TreeNode* node, vector<int>& res)
{
res.push_back(node->val);
}
};
algorithme 2 itératives:
L'idée d'un algorithme itératif peut être étendu à l'ordre et après l'ordre, est un algorithme itératif universel. Cependant, l'algorithme est complexe et difficile, les notes n'écrivent pas, parce que l'écriture ne sert à rien.
class Solution {
public:
vector<int> res;
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode*> s;
while (true)
{
vistAlongLeft(s, root);
if (s.empty()) return res;
root = s.top();
s.pop();
}
}
void vistAlongLeft(stack<TreeNode*>& s, TreeNode* t)
{
while (t)
{
res.push_back(t->val);
s.push(t->right);
t = t->left;
}
}
};