当前位置:   article > 正文

day10_LC学习计划:数据结构入门_root = [1,null,2,3]

root = [1,null,2,3]

144.二叉树的前序遍历

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例 1:


输入:root = [1,null,2,3]
输出:[1,2,3]
示例 2:

输入:root = []
输出:[]
示例 3:

输入:root = [1]
输出:[1]
示例 4:


输入:root = [1,2]
输出:[1,2]
示例 5:


输入:root = [1,null,2]
输出:[1,2]
 

提示:

树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
 

进阶:递归算法很简单,你可以通过迭代算法完成吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-preorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

一、idea:

前中后序遍历真数据结构基操了,迭代和递归,不过还是有不会写的地方,果然光是看懂真不行。

二、解法:

略。

三、代码实现细节的学习:

  1. 在递归时,一开始不知道如何让保存结果的数组序号向后移动。
  2. 重新理解了一下C中的指针,当指针已经开辟了空间的时候,*p便可以像只有一位数字的p数组的p[0]处存放int类型的数据。
  3. *p=&a,在没有开辟内存空间时候,指针指向地址才是正确的赋值方式。
  4. C中的指针在传递的过程中也是传递的地址,所以在不同的函数中

1、递归,解答则避免了全局变量内存空间的开辟。

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * struct TreeNode *left;
  6. * struct TreeNode *right;
  7. * };
  8. */
  9. /**
  10. * Note: The returned array must be malloced, assume caller calls free().
  11. */
  12. int *ret;
  13. int i;
  14. int* preorderTraversal(struct TreeNode* root, int* returnSize){
  15. i=0;
  16. ret=malloc(sizeof(int)*100);
  17. preorder(root);
  18. *returnSize=i;
  19. return ret;
  20. }
  21. void preorder(struct TreeNode *root){
  22. if(root==NULL) return;
  23. ret[i++]=root->val;
  24. preorder(root->left);
  25. preorder(root->right);
  26. }

2、在迭代时,题解中的思想里,栈中只保存上一个该向右结点遍历的结点。

while里的第一个node!=NULL是为了保证右子树和栈不都为空,第二个是为了保证左子树不为空。

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * struct TreeNode *left;
  6. * struct TreeNode *right;
  7. * };
  8. */
  9. /**
  10. * Note: The returned array must be malloced, assume caller calls free().
  11. */
  12. int* preorderTraversal(struct TreeNode* root, int* returnSize){
  13. int *ret=malloc(sizeof(int)*100);
  14. *returnSize=0;
  15. if(root==NULL) return ret;
  16. struct TreeNode* stack[100];
  17. struct TreeNode* node=root;
  18. int top=-1;
  19. while(node!=NULL||top>-1){
  20. while(node!=NULL){
  21. ret[(*returnSize)++]=node->val;
  22. stack[++top]=node;
  23. node=node->left;
  24. }
  25. node=stack[top--];
  26. node=node->right;
  27. }
  28. return ret;
  29. }

 3、Morris算法,第一次接触到,常看常新,自己实现的时候错误的地方已经标注在代码上了。

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * struct TreeNode *left;
  6. * struct TreeNode *right;
  7. * };
  8. */
  9. /**
  10. * Note: The returned array must be malloced, assume caller calls free().
  11. */
  12. int* preorderTraversal(struct TreeNode* root, int* returnSize){
  13. int *ret=malloc(sizeof(int)*100);
  14. *returnSize=0;
  15. if(root==NULL) return ret;
  16. struct TreeNode *p1=root,*p2=NULL;
  17. while(p1!=NULL){
  18. p2=p1->left;
  19. if(p2!=NULL){
  20. while(p2->right!=NULL&&p2->right!=p1){
  21. p2=p2->right;
  22. }
  23. if(p2->right==NULL){
  24. ret[(*returnSize)++]=p1->val;
  25. p2->right=p1;
  26. p1=p1->left;
  27. continue;//不加这个就直接向右走了
  28. }else{
  29. p2->right=NULL;//如果p2的右子树不为空,那就直接恢复原本的树就可以了
  30. }
  31. }else{
  32. ret[(*returnSize)++]=p1->val;//如果p2为空,说明左子树为空。
  33. }
  34. p1=p1->right;
  35. }
  36. return ret;
  37. }

 94.二叉树的中序遍历

给定一个二叉树的根节点 root ,返回它的 中序 遍历。

示例 1:


输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:

输入:root = []
输出:[]
示例 3:

输入:root = [1]
输出:[1]
示例 4:


输入:root = [1,2]
输出:[2,1]
示例 5:


输入:root = [1,null,2]
输出:[1,2]
 

提示:

树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
 

进阶: 递归算法很简单,你可以通过迭代算法完成吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

一、idea:

二、解法:

三、代码实现细节的学习: 

1、递归

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * struct TreeNode *left;
  6. * struct TreeNode *right;
  7. * };
  8. */
  9. /**
  10. * Note: The returned array must be malloced, assume caller calls free().
  11. */
  12. int* inorderTraversal(struct TreeNode* root, int* returnSize){
  13. int *ret=malloc(sizeof(int)*100);
  14. *returnSize=0;
  15. inorder(root,ret,returnSize);
  16. return ret;
  17. }
  18. void inorder(struct TreeNode* root, int* ret, int* returnSize){
  19. if(root==NULL) return;
  20. inorder(root->left, ret, returnSize);
  21. ret[(*returnSize)++]=root->val;
  22. inorder(root->right, ret, returnSize);
  23. }

2、迭代

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * struct TreeNode *left;
  6. * struct TreeNode *right;
  7. * };
  8. */
  9. /**
  10. * Note: The returned array must be malloced, assume caller calls free().
  11. */
  12. int* inorderTraversal(struct TreeNode* root, int* returnSize){
  13. int *ret=malloc(sizeof(int)*100);
  14. *returnSize=0;
  15. if(root==NULL) return ret;
  16. struct TreeNode* stack[100];
  17. int top=-1;
  18. while(root!=NULL||top>-1){//应该保证栈不为空或者root不为空就行
  19. while(root!=NULL){
  20. stack[++top]=root;//在这里应该放入当前节点
  21. root=root->left;
  22. }
  23. root=stack[top--];//要先从栈中取出
  24. ret[(*returnSize)++]=root->val;
  25. root=root->right;
  26. }
  27. return ret;
  28. }

3、Morris算法

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * struct TreeNode *left;
  6. * struct TreeNode *right;
  7. * };
  8. */
  9. /**
  10. * Note: The returned array must be malloced, assume caller calls free().
  11. */
  12. int* inorderTraversal(struct TreeNode* root, int* returnSize){
  13. int *ret=malloc(sizeof(int)*100);
  14. *returnSize=0;
  15. struct TreeNode* node=root;
  16. while(node!=NULL){
  17. if(node->left!=NULL){
  18. struct TreeNode* tmp=node->left;//按算法这里应该是node->left!!
  19. while(tmp->right!=NULL&&tmp->right!=node){
  20. tmp=tmp->right;
  21. }
  22. if(tmp->right==NULL){
  23. tmp->right=node;
  24. node=node->left;//这里不用continue,因为这次的写法,指针向右写在了else里边
  25. //continue;
  26. }else{
  27. ret[(*returnSize)++]=node->val;
  28. tmp->right=NULL;//这个前驱的右子树只是一个标记作用,标记左子树是否完成遍历。
  29. node=node->right;
  30. }
  31. }else{
  32. ret[(*returnSize)++]=node->val;
  33. node=node->right;
  34. }
  35. //node=node->right;不理解写在这为什么会有空指针异常
  36. }
  37. return ret;
  38. }

145.二叉树的后序遍历

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。

示例 1:


输入:root = [1,null,2,3]
输出:[3,2,1]
示例 2:

输入:root = []
输出:[]
示例 3:

输入:root = [1]
输出:[1]
 

提示:

树中节点的数目在范围 [0, 100] 内
-100 <= Node.val <= 100
 

进阶:递归算法很简单,你可以通过迭代算法完成吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

一、idea:

二、解法:

三、代码实现细节的学习: 

1、递归

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * struct TreeNode *left;
  6. * struct TreeNode *right;
  7. * };
  8. */
  9. /**
  10. * Note: The returned array must be malloced, assume caller calls free().
  11. */
  12. int* postorderTraversal(struct TreeNode* root, int* returnSize){
  13. int *ret=malloc(sizeof(int)*100);
  14. *returnSize=0;
  15. postorder(root,ret,returnSize);
  16. return ret;
  17. }
  18. void postorder(struct TreeNode* root, int* ret, int* returnSize){
  19. if(root==NULL) return;
  20. postorder(root->left,ret,returnSize);
  21. postorder(root->right,ret,returnSize);
  22. ret[(*returnSize)++]=root->val;
  23. }

2、迭代,自己该注意的已经写了注释。

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * struct TreeNode *left;
  6. * struct TreeNode *right;
  7. * };
  8. */
  9. /**
  10. * Note: The returned array must be malloced, assume caller calls free().
  11. */
  12. int* postorderTraversal(struct TreeNode* root, int* returnSize){
  13. int *ret=malloc(sizeof(int)*100);
  14. *returnSize=0;
  15. if(root==NULL) return ret;
  16. struct TreeNode* stack[100],*prev;
  17. int top=-1;
  18. while(root!=NULL||top>-1){
  19. while(root!=NULL){
  20. stack[++top]=root;
  21. root=root->left;
  22. }
  23. root=stack[top--];
  24. if(root->right==NULL||root->right==prev){
  25. ret[(*returnSize)++]=root->val;
  26. prev=root;
  27. root=NULL;//后序遍历用栈需要有一个置空指针操作,还需要判断被置空的是不是栈里
  28. }else{//弹出的下一个节点的右节点,如果是右节点,说明左右子节点都已经遍历了
  29. stack[++top]=root;//如果都不是,说明是根节点的左子节点,放回栈里继续等待遍历。
  30. root=root->right;
  31. }
  32. }
  33. return ret;
  34. }

3、Morris算法,整个算法不能说算太懂,搭配上倒序算法更是不知道为什么可以这样,后续有时间再深究吧。

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * struct TreeNode *left;
  6. * struct TreeNode *right;
  7. * };
  8. */
  9. /**
  10. * Note: The returned array must be malloced, assume caller calls free().
  11. */
  12. void addPath(int *ret, int *returnSize, struct TreeNode* node){
  13. int count=0;//简单的反转算法
  14. while(node!=NULL){//倒序算法,目前还没有弄懂原理。
  15. count++;
  16. ret[(*returnSize)++]=node->val;
  17. node=node->right;
  18. }
  19. for(int i=*returnSize-count,j=*returnSize-1;i<j;i++,j--){
  20. int tmp=ret[i];
  21. ret[i]=ret[j];
  22. ret[j]=tmp;
  23. }
  24. }
  25. int* postorderTraversal(struct TreeNode* root, int* returnSize){
  26. int *ret=malloc(sizeof(int)*100);//这个Morris算法的访问顺序是4,2,5,1,3,6中序序列
  27. *returnSize=0;
  28. if(root==NULL) return ret;
  29. struct TreeNode *p1=root,*p2=NULL;
  30. while(p1!=NULL){
  31. p2=p1->left;
  32. if(p2!=NULL){
  33. while(p2->right!=NULL&&p2->right!=p1){
  34. p2=p2->right;
  35. }
  36. if(p2->right==NULL){
  37. p2->right=p1;
  38. p1=p1->left;
  39. continue;
  40. }else{
  41. p2->right=NULL;
  42. addPath(ret,returnSize,p1->left);
  43. }
  44. }
  45. p1=p1->right;
  46. }
  47. addPath(ret,returnSize,root);
  48. return ret;
  49. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/50412
推荐阅读
相关标签
  

闽ICP备14008679号