当前位置:   article > 正文

二叉树遍历(c语言)_二叉树遍历c语言代码

二叉树遍历c语言代码

leetcode 144

方法一:递归遍历

  1. int* preorderTraversal(struct TreeNode* root,int* returnSize);
  2. void preorder(struct TreeNode* root,int result[],int *returnSize);
  3. void preorder(struct TreeNode* root,int result[],int *returnSize)
  4. {
  5. if(root==NULL)
  6. {
  7. return;
  8. }
  9. result[(*returnSize)++]=root->val;
  10. preorder(root->left,result,returnSize);
  11. preorder(root->right,result,returnSize);
  12. }
  13. int* preorderTraversal(struct TreeNode* root,int* returnSize)
  14. {
  15. int *result;
  16. result=(int *)malloc(2000*sizeof(int));
  17. (*returnSize)=0;
  18. preorder(root,result,returnSize);
  19. return result;
  20. }

方法二:迭代遍历

  1. int p_top=0;
  2. struct TreeNode* stack[10010];
  3. void push(struct TreeNode *node);
  4. struct TreeNode *pop(void);
  5. int isempty(void);
  6. int* preorderTraversal(struct TreeNode* root, int* returnSize)
  7. {
  8. int* res;
  9. res=(int *)malloc(2000*sizeof(int));
  10. (*returnSize)=0;
  11. while(!isempty()||root!=NULL)
  12. {
  13. while((root)!=NULL)
  14. {
  15. push(root);
  16. res[(*returnSize)++]=root->val;
  17. root=root->left;
  18. }
  19. root=pop();
  20. root=root->right;
  21. }
  22. return res;
  23. }
  24. void push(struct TreeNode *node)
  25. {
  26. p_top++;
  27. stack[p_top]=node;
  28. return ;
  29. }
  30. struct TreeNode *pop(void)
  31. {
  32. return stack[p_top--];
  33. }
  34. int isempty(void)
  35. {
  36. if(p_top==0) return 1;
  37. else return 0;
  38. }

方法三:Morris遍历

Morris 遍历的核心思想是利用树的大量空闲指针,实现空间开销的极限缩减。其前序遍历规则总结如下:

新建临时节点,令该节点为 root;

如果当前节点的左子节点为空,将当前节点加入答案,并遍历当前节点的右子节点;

如果当前节点的左子节点不为空,在当前节点的左子树中找到当前节点在中序遍历下的前驱节点:

        如果前驱节点的右子节点为空,将前驱节点的右子节点设置为当前节点。然后将当前节点加入答案,并将前驱节点的右子节点更新为当前节点。当前节点更新为当前节点的左子节点。

        如果前驱节点的右子节点为当前节点,将它的右子节点重新设为空。当前节点更新为当前节点的右子节点。

重复步骤 2 和步骤 3,直到遍历结束。

  1. int* preorderTraversal(struct TreeNode* root, int* returnSize)
  2. {
  3. int* res;
  4. res=(int *)malloc(2000*sizeof(int));
  5. (*returnSize)=0;
  6. struct TreeNode *p1,*p2;
  7. p1=root;p2=NULL;
  8. while(p1!=NULL)
  9. {
  10. if(p1->left!=NULL)
  11. {
  12. p2=p1->left;
  13. while(p2->right!=NULL&&p2->right!=p1)
  14. {
  15. p2=p2->right;
  16. }
  17. if(p2->right==NULL)
  18. {
  19. res[(*returnSize)++]=p1->val;
  20. p2->right=p1;
  21. p1=p1->left;
  22. continue;
  23. }
  24. else if(p2->right==p1)
  25. {
  26. p2->right=NULL;
  27. }
  28. }
  29. else if(p1->left==NULL)
  30. {
  31. res[(*returnSize)++]=p1->val;
  32. }
  33. p1=p1->right;
  34. }
  35. return res;
  36. }

理解:

Morris其实解决了一个常规循环中循环到叶子节点后难以回到根节点的问题。 我们都知道前序遍历是先左后右,那么对任一节点p1来说,其右子树p1right所有节点必然在左子树p1left之后。代码中第二个while做的是,在p1left里一直往右,直到找不到更右的点,记这一点为p2。然后把p1right接到p2的右边。 这样既保证了p1right在p1left所有点之后,又不需要再回到p1节点。 即在正常的往下循环的过程中,不断把右半部分剪下来,接到左半部分的最右下

方法四:标记遍历法

  1. struct mystack
  2. {
  3. struct TreeNode *node;
  4. int judge;
  5. };
  6. struct mystack stack[10010];
  7. int top=0;
  8. int* inorderTraversal(struct TreeNode* root, int* returnSize){
  9. int *array;
  10. array=(int *)malloc(2000*sizeof(int));
  11. (*returnSize)=0;
  12. if(root==NULL) return NULL;
  13. stack[top].node=root->right;
  14. stack[top].judge=0;top++;
  15. stack[top].node=root->left;
  16. stack[top].judge=0;top++;
  17. stack[top].node=root;
  18. stack[top].judge=1;top++;
  19. while(top>0)
  20. {
  21. root=stack[--top].node;
  22. if(root==NULL) continue;
  23. else if(stack[top].judge==0)
  24. {
  25. stack[top].node=root->right;
  26. stack[top].judge=0;top++;
  27. stack[top].node=root->left;
  28. stack[top].judge=0;top++;
  29. stack[top].node=root;
  30. stack[top].judge=1;top++;
  31. }
  32. else if(stack[top].judge==1)
  33. {
  34. array[(*returnSize)++]=root->val;
  35. }
  36. }
  37. return array;
  38. }

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

闽ICP备14008679号