鱼C论坛

 找回密码
 立即注册
查看: 550|回复: 4

[已解决]二叉树的非递归算法

[复制链接]
发表于 2023-4-18 16:33:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
分别设计出先序、中序和后序遍历二叉树的非递归算法。
最佳答案
2023-4-18 16:42:05
以下是C语言中实现二叉树非递归遍历的代码。这里提供了先序、中序和后序遍历的非递归算法。

首先,定义二叉树结构体:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>

  4. typedef struct TreeNode {
  5.     int val;
  6.     struct TreeNode *left;
  7.     struct TreeNode *right;
  8. } TreeNode;
复制代码


接下来,定义栈结构体:
  1. typedef struct Stack {
  2.     TreeNode **array;
  3.     int top;
  4.     int size;
  5. } Stack;

  6. Stack *createStack(int size) {
  7.     Stack *stack = (Stack *)malloc(sizeof(Stack));
  8.     stack->array = (TreeNode **)malloc(size * sizeof(TreeNode *));
  9.     stack->top = -1;
  10.     stack->size = size;
  11.     return stack;
  12. }

  13. bool isStackEmpty(Stack *stack) {
  14.     return stack->top == -1;
  15. }

  16. bool isStackFull(Stack *stack) {
  17.     return stack->top == stack->size - 1;
  18. }

  19. void push(Stack *stack, TreeNode *node) {
  20.     if (isStackFull(stack)) return;
  21.     stack->array[++stack->top] = node;
  22. }

  23. TreeNode *pop(Stack *stack) {
  24.     if (isStackEmpty(stack)) return NULL;
  25.     return stack->array[stack->top--];
  26. }
复制代码


先序遍历非递归算法:
  1. void preorderTraversal(TreeNode *root) {
  2.     if (root == NULL) return;
  3.     Stack *stack = createStack(100); // 根据实际情况调整栈大小
  4.     TreeNode *node = root;

  5.     while (node != NULL || !isStackEmpty(stack)) {
  6.         while (node != NULL) {
  7.             printf("%d ", node->val);
  8.             push(stack, node);
  9.             node = node->left;
  10.         }
  11.         node = pop(stack);
  12.         node = node->right;
  13.     }

  14.     free(stack->array);
  15.     free(stack);
  16. }
复制代码


中序遍历非递归算法:
  1. void inorderTraversal(TreeNode *root) {
  2.     if (root == NULL) return;
  3.     Stack *stack = createStack(100); // 根据实际情况调整栈大小
  4.     TreeNode *node = root;

  5.     while (node != NULL || !isStackEmpty(stack)) {
  6.         while (node != NULL) {
  7.             push(stack, node);
  8.             node = node->left;
  9.         }
  10.         node = pop(stack);
  11.         printf("%d ", node->val);
  12.         node = node->right;
  13.     }

  14.     free(stack->array);
  15.     free(stack);
  16. }
复制代码


后序遍历非递归算法:
  1. void postorderTraversal(TreeNode *root) {
  2.     if (root == NULL) return;
  3.     Stack *stack = createStack(100); // 根据实际情况调整栈大小
  4.     Stack *output = createStack(100); // 存储后序遍历结果的栈
  5.     TreeNode *node = root;

  6.     while (node != NULL || !isStackEmpty(stack)) {
  7.         while (node != NULL) {
  8.             push(output, node);
  9.             push(stack, node);
  10.             node = node->right;
  11.         }
  12.         node = pop(stack);
  13.         node = node->left;
  14.     }

  15.     while (!isStackEmpty(output)) {
  16.         printf("%d ", pop(output)->val);
  17.     }

  18.     free(stack->array);
  19.     free(stack);
  20.     free(output->array);
  21.     free(output);
  22. }
复制代码


现在,你可以使用这些非递归算法来分别实现二叉树的先序、中序和后序遍历。这些算法的基本思路是使用一个栈来存储遍历过程中的节点,这样就可以避免使用递归。栈的大小可以根据实际情况调整。当遍历完整棵树时,释放栈所占用的内存。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-18 16:39:50 | 显示全部楼层
  1. #二叉树遍历操作实现的非递归算法
  2. #先序遍历
  3. def preOrder2(root):
  4.     p = root
  5.     s = LinkStack()
  6.     s.push(p)
  7.     while not s.isEmpty():
  8.         p = s.pop()
  9.         print(p.data,end=' ')
  10.         while p is not None:
  11.             if p.rchild is not None:
  12.                 print(p.lchild.data,end=' ')
  13.             if p.lchild is not None:
  14.                 s.push(p.rchild)
  15.                 p = p.lchild
  16. #中序遍历
  17. def inOeder2(root):
  18.     p = root
  19.     s = LinkStack()
  20.     s.push(p)
  21.     while not s.isEmpty():
  22.         while p.lchild is not None:
  23.             p = p.lchild
  24.             s.push(p)
  25.         p = p.pop()
  26.         print(p.data,end=' ')
  27.         if p.rchild is not None:
  28.             s.push(p.rchild)
  29. #后序遍历
  30. def postOrder2(root):
  31.     p = root
  32.     t = None
  33.     flag = False
  34.     s = LinkStack()
  35.     if p is not None:
  36.         s.push(p)
  37.         while p.lchild is None:
  38.             p = p.push(p)
  39.             s.push(p)
  40.         while not s.isEmpty() and flag:
  41.             if p.rchild == t or p.rchild is None:
  42.                 print(p.data,end=' ')
  43.                 flag = True
  44.                 t = p
  45.                 s.pop
  46.             else:
  47.                 s.push(p.rchild)
  48.                 flag = False
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-18 16:42:05 | 显示全部楼层    本楼为最佳答案   
以下是C语言中实现二叉树非递归遍历的代码。这里提供了先序、中序和后序遍历的非递归算法。

首先,定义二叉树结构体:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>

  4. typedef struct TreeNode {
  5.     int val;
  6.     struct TreeNode *left;
  7.     struct TreeNode *right;
  8. } TreeNode;
复制代码


接下来,定义栈结构体:
  1. typedef struct Stack {
  2.     TreeNode **array;
  3.     int top;
  4.     int size;
  5. } Stack;

  6. Stack *createStack(int size) {
  7.     Stack *stack = (Stack *)malloc(sizeof(Stack));
  8.     stack->array = (TreeNode **)malloc(size * sizeof(TreeNode *));
  9.     stack->top = -1;
  10.     stack->size = size;
  11.     return stack;
  12. }

  13. bool isStackEmpty(Stack *stack) {
  14.     return stack->top == -1;
  15. }

  16. bool isStackFull(Stack *stack) {
  17.     return stack->top == stack->size - 1;
  18. }

  19. void push(Stack *stack, TreeNode *node) {
  20.     if (isStackFull(stack)) return;
  21.     stack->array[++stack->top] = node;
  22. }

  23. TreeNode *pop(Stack *stack) {
  24.     if (isStackEmpty(stack)) return NULL;
  25.     return stack->array[stack->top--];
  26. }
复制代码


先序遍历非递归算法:
  1. void preorderTraversal(TreeNode *root) {
  2.     if (root == NULL) return;
  3.     Stack *stack = createStack(100); // 根据实际情况调整栈大小
  4.     TreeNode *node = root;

  5.     while (node != NULL || !isStackEmpty(stack)) {
  6.         while (node != NULL) {
  7.             printf("%d ", node->val);
  8.             push(stack, node);
  9.             node = node->left;
  10.         }
  11.         node = pop(stack);
  12.         node = node->right;
  13.     }

  14.     free(stack->array);
  15.     free(stack);
  16. }
复制代码


中序遍历非递归算法:
  1. void inorderTraversal(TreeNode *root) {
  2.     if (root == NULL) return;
  3.     Stack *stack = createStack(100); // 根据实际情况调整栈大小
  4.     TreeNode *node = root;

  5.     while (node != NULL || !isStackEmpty(stack)) {
  6.         while (node != NULL) {
  7.             push(stack, node);
  8.             node = node->left;
  9.         }
  10.         node = pop(stack);
  11.         printf("%d ", node->val);
  12.         node = node->right;
  13.     }

  14.     free(stack->array);
  15.     free(stack);
  16. }
复制代码


后序遍历非递归算法:
  1. void postorderTraversal(TreeNode *root) {
  2.     if (root == NULL) return;
  3.     Stack *stack = createStack(100); // 根据实际情况调整栈大小
  4.     Stack *output = createStack(100); // 存储后序遍历结果的栈
  5.     TreeNode *node = root;

  6.     while (node != NULL || !isStackEmpty(stack)) {
  7.         while (node != NULL) {
  8.             push(output, node);
  9.             push(stack, node);
  10.             node = node->right;
  11.         }
  12.         node = pop(stack);
  13.         node = node->left;
  14.     }

  15.     while (!isStackEmpty(output)) {
  16.         printf("%d ", pop(output)->val);
  17.     }

  18.     free(stack->array);
  19.     free(stack);
  20.     free(output->array);
  21.     free(output);
  22. }
复制代码


现在,你可以使用这些非递归算法来分别实现二叉树的先序、中序和后序遍历。这些算法的基本思路是使用一个栈来存储遍历过程中的节点,这样就可以避免使用递归。栈的大小可以根据实际情况调整。当遍历完整棵树时,释放栈所占用的内存。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-18 17:10:47 | 显示全部楼层
本帖最后由 wuliangtdi 于 2023-4-18 17:20 编辑

C语言版
先定义一些内容:
  1. typedef struct StackNode {
  2.     void* data;
  3.     struct StackNode* next;
  4. } StackNode;

  5. typedef struct Stack {
  6.     StackNode* top;
  7.     int size;
  8. } Stack;

  9. Stack* createStack() {
  10.     Stack* stack = (Stack*)malloc(sizeof(Stack));
  11.     stack->top = NULL;
  12.     stack->size = 0;
  13.     return stack;
  14. }

  15. void destroyStack(Stack* stack) {
  16.     if (stack == NULL) return;
  17.     while (!isEmpty(stack)) {
  18.         StackNode* node = stack->top;
  19.         stack->top = stack->top->next;
  20.         free(node);
  21.         stack->size--;
  22.     }
  23.     free(stack);
  24. }

  25. bool isEmpty(Stack* stack) {
  26.     return stack->top == NULL;
  27. }

  28. void push(Stack* stack, void* data) {
  29.     StackNode* node = (StackNode*)malloc(sizeof(StackNode));
  30.     node->data = data;
  31.     node->next = stack->top;
  32.     stack->top = node;
  33.     stack->size++;
  34. }

  35. void* pop(Stack* stack) {
  36.     if (isEmpty(stack)) return NULL;
  37.     StackNode* node = stack->top;
  38.     void* data = node->data;
  39.     stack->top = stack->top->next;
  40.     free(node);
  41.     stack->size--;
  42.     return data;
  43. }
复制代码

前序遍历:
  1. void preorderTraversal(TreeNode* root) {
  2.     if (root == NULL) return;

  3.     Stack* stack = createStack();
  4.     push(stack, root);

  5.     while (!isEmpty(stack)) {
  6.         TreeNode* node = (TreeNode*)pop(stack);
  7.         printf("%d ", node->val);

  8.         if (node->right != NULL) push(stack, node->right);
  9.         if (node->left != NULL) push(stack, node->left);
  10.     }

  11.     destroyStack(stack);
  12. }
复制代码

中序遍历:
  1. void inorderTraversal(TreeNode* root) {
  2.     if (root == NULL) return;

  3.     Stack* stack = createStack();
  4.     TreeNode* node = root;

  5.     while (!isEmpty(stack) || node != NULL) {
  6.         if (node != NULL) {
  7.             push(stack, node);
  8.             node = node->left;
  9.         } else {
  10.             node = (TreeNode*)pop(stack);
  11.             printf("%d ", node->val);
  12.             node = node->right;
  13.         }
  14.     }

  15.     destroyStack(stack);
  16. }
复制代码

后序遍历:
  1. void postorderTraversal(TreeNode* root) {
  2.     if (root == NULL) return;

  3.     Stack* stack1 = createStack();
  4.     Stack* stack2 = createStack();

  5.     push(stack1, root);

  6.     while (!isEmpty(stack1)) {
  7.         TreeNode* node = (TreeNode*)pop(stack1);
  8.         push(stack2, node);

  9.         if (node->left != NULL) push(stack1, node->left);
  10.         if (node->right != NULL) push(stack1, node->right);
  11.     }

  12.     while (!isEmpty(stack2)) {
  13.         TreeNode* node = (TreeNode*)pop(stack2);
  14.         printf("%d ", node->val);
  15.     }

  16.     destroyStack(stack1);
  17.     destroyStack(stack2);
  18. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-18 17:19:01 | 显示全部楼层
java版:
先定义一些内容
  1. public class TreeNode {
  2.     int val;
  3.     TreeNode left;
  4.     TreeNode right;
  5.    
  6.     public TreeNode(int val) {
  7.         this.val = val;
  8.         left = null;
  9.         right = null;
  10.     }
  11. }
  12. //实现泛型栈
  13. public class Stack<T> {
  14.     private Node<T> top;
  15.     private int size;

  16.     public Stack() {
  17.         top = null;
  18.         size = 0;
  19.     }

  20.     public void push(T data) {
  21.         Node<T> node = new Node<>(data);
  22.         node.next = top;
  23.         top = node;
  24.         size++;
  25.     }

  26.     public T pop() {
  27.         if (isEmpty()) return null;
  28.         T data = top.data;
  29.         top = top.next;
  30.         size--;
  31.         return data;
  32.     }

  33.     public T peek() {
  34.         if (isEmpty()) return null;
  35.         return top.data;
  36.     }

  37.     public boolean isEmpty() {
  38.         return top == null;
  39.     }

  40.     public int size() {
  41.         return size;
  42.     }

  43.     private static class Node<T> {
  44.         T data;
  45.         Node<T> next;

  46.         public Node(T data) {
  47.             this.data = data;
  48.             next = null;
  49.         }
  50.     }
  51. }

复制代码


先序遍历:
  1. public void preorderTraversal(TreeNode root) {
  2.     if (root == null) return;
  3.     Stack<TreeNode> stack = new Stack<>();
  4.     stack.push(root);

  5.     while (!stack.isEmpty()) {
  6.         TreeNode node = stack.pop();
  7.         System.out.print(node.val + " ");

  8.         if (node.right != null) stack.push(node.right);
  9.         if (node.left != null) stack.push(node.left);
  10.     }
  11. }
复制代码


中序遍历:
  1. public void inorderTraversal(TreeNode root) {
  2.     if (root == null) return;
  3.     Stack<TreeNode> stack = new Stack<>();
  4.     TreeNode node = root;

  5.     while (!stack.isEmpty() || node != null) {
  6.         if (node != null) {
  7.             stack.push(node);
  8.             node = node.left;
  9.         } else {
  10.             node = stack.pop();
  11.             System.out.print(node.val + " ");
  12.             node = node.right;
  13.         }
  14.     }
  15. }
复制代码


后序遍历:
  1. public void postorderTraversal(TreeNode root) {
  2.     if (root == null) return;
  3.     Stack<TreeNode> stack1 = new Stack<>();
  4.     Stack<TreeNode> stack2 = new Stack<>();
  5.     stack1.push(root);

  6.     while (!stack1.isEmpty()) {
  7.         TreeNode node = stack1.pop();
  8.         stack2.push(node);

  9.         if (node.left != null) stack1.push(node.left);
  10.         if (node.right != null) stack1.push(node.right);
  11.     }

  12.     while (!stack2.isEmpty()) {
  13.         TreeNode node = stack2.pop();
  14.         System.out.print(node.val + " ");
  15.     }
  16. }
复制代码

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-1 23:59

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表