无限循环的原因? (迭代有序遍历实现)C ++

时间:2020-08-05 04:40:04

标签: c++ algorithm traversal inorder

问题:迭代实现有序遍历。

我的尝试:(导致无法调试的无限循环)非常感谢任何帮助或建议

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
#include <vector>
#include <stack>
#include <unordered_set>
using namespace std;

class Solution {
    
    public:
    
        vector<int> inorderTraversal(TreeNode* root) {
            
            //iterative sol:
            vector<int> sol;
            stack<TreeNode*> dfs;
            dfs.push(root);
            unordered_set<TreeNode*> visited;
            visited.insert({root});
            TreeNode* temp;
            
            while (!dfs.empty()) {
                
                if (dfs.top()->left != nullptr && visited.find(dfs.top()->left) == visited.end()) {
                    dfs.push(dfs.top()->left);
                    visited.insert({dfs.top()->left});
                }
                else {
                    sol.push_back(dfs.top()->val);
                    temp = dfs.top();
                    dfs.pop();
                    
                    if (temp->right != nullptr && visited.find(temp->right) == visited.end()) {
                        dfs.push(temp->right);
                        visited.insert({temp->right});
                    }
                }     
                          
            }
            
            return sol;
            
        }
};

编辑:我没有TreeNode的特定内部定义,但是如果您要运行此问题,请签出:https://leetcode.com/problems/binary-tree-inorder-traversal/

3 个答案:

答案 0 :(得分:3)

问题出在这里:

#ifndef queyeu
#define queyeu

#define max 40

struct node *A[max];
int rear;
int front;



int isempty(){
    return (front==-1 && rear==-1)?1:0;
    
}

int isfull(){
    return ((rear+1)%max==front)?1:0;
}

void enqueue(struct node *a){
    if(isfull()){
        printf("queue full");
            return;
    }
    if(isempty()){
        front=rear=0;
    }
    else{
        rear=(rear+1)%max;
    }
    A[rear]=a;
}

struct node *dequeue(){
    struct node *b;
    b=A[front];
    if(isempty()){
        printf("the queue is empty");
    }
    else if(front==rear){
        front=rear=-1;
    }else {
        front=(front+1) %max;
    }
    return b;
}

struct node *fron(){
    return A[front];
}

#endif

您要堆叠(然后dfs.push(dfs.top()->left); visited.insert(dfs.top()->left); 会改变),然后在下一行访问dfs.top()

答案 1 :(得分:2)

您正在此处的第一行中修改堆栈

PlayerPanel

您要做的是将先前的Driver标记为已访问,但是您要在堆栈顶部添加更多元素,因此新的public class Driver { public static void main(String args[]) { JFrame frame = new JFrame(); frame.setSize(1000, 500); JPanel background = new JPanel(); background.setBackground(Color.BLACK); PlayerPanel player = new PlayerPanel(); background.add(player); frame.add(background); frame.setVisible(true); } } 是不同的元素。

要解决此问题,您应该使用前一个 dfs.push(dfs.top()->left); visited.insert({dfs.top()->left}); 存储在不同的变量中。

作为最佳实践,正在处理的变量或对象应该是不可变的,因为堆栈不是不可变的,因此在插入变量或进行其他计算时不要使用其dfs.top()->left。而是将您所需的变量存储在dfs.top()这样的不可变对象中

dfs.top()->left

答案 2 :(得分:1)

只需两个简单的规则即可实现迭代有序遍历。

如果您在节点X上,那么:

  1. 如果X有一个正确的子节点,则移至该正确的子节点,并遵循尽可能多的左侧链接以找到下一个节点。
  2. 否则,在右侧找到X的最接近的祖先,即,其左子树包含X的最接近的祖先。如果没有这样的祖先,就可以完成。

如果您的树没有父链接,那么您将需要一个堆栈来存储正确的祖先,但不需要访问集:

vector<int> inorderTraversal(TreeNode* tree) {
    vector<int> ret;
    stack<TreeNode *> nextParents;
    for(;tree; tree = tree.left) {
        nextParents.push(tree);
    }
    while(!nextParents.empty()) {
        tree = nextParents.pop();
        ret.push_back(tree->val);
        for(tree = tree.right; tree; tree = tree.left) {
            nextParents.push(tree);
        }
    }
    return ret;
}
相关问题