级别顺序遍历二叉树

问题描述 投票:8回答:6
void traverse(Node* root)
{
    queue<Node*> q;

    Node* temp_node= root;

    while(temp_node)
    {
        cout<<temp_node->value<<endl;

        if(temp_node->left)
            q.push(temp_node->left);

        if(temp_node->right)
            q.push(temp_node->right);

        if(!q.empty())
        {
            temp_node = q.front();
            q.pop();
        }
        else
            temp_node = NULL;
   }
 }

上面发布的代码是我的级别订单遍历代码。这段代码对我来说很好,但我不喜欢的一件事是我明确地初始化temp_node = NULL或者我使用break。但它对我来说似乎不是一个好的代码。

是否有比这更好的实现或如何使这个代码更好?

c++ algorithm binary-tree breadth-first-search tree-traversal
6个回答
13
投票
void traverse(Node* root)
{
    queue<Node*> q;

    if (root) {
        q.push(root);
    }
    while (!q.empty())
    {
        const Node * const temp_node = q.front();
        q.pop();
        cout<<temp_node->value<<"\n";

        if (temp_node->left) {
            q.push(temp_node->left);
        }
        if (temp_node->right) {
            q.push(temp_node->right);
        }
    }
}

在那里,没有更特殊的情况。并且压痕被清理干净,因此可以更容易理解。

或者:

void traverse(Node* root)
{
    queue<Node*> q;

    if (!root) {
        return;
    }
    for (q.push(root); !q.empty(); q.pop()) {
        const Node * const temp_node = q.front();
        cout<<temp_node->value<<"\n";

        if (temp_node->left) {
            q.push(temp_node->left);
        }
        if (temp_node->right) {
            q.push(temp_node->right);
        }
    }
}

完成了for循环。就个人而言,我喜欢额外的变量。变量名比一直说'q.front()`更简单。


3
投票

你可以这样试试:

struct Node
{
    char data;
    Node* left;
    Node* right;
};
void LevelOrder(Node* root)
{
    if(root == NULL) return;
    queue<Node*> Q;
    Q.push(root);
    while(!Q.empty())
    {
        Node* current = Q.front();
        cout<< current->data << " ";
        if(current->left != NULL) Q.push(current->left);
        if(current->right != NULL) Q.push(current->right);
        Q.pop();
    }
}

2
投票

现有代码的一个严重问题是它在空树(root = NULL)上调用时崩溃。

您需要决定是否要在队列中使用NULL指针。

如果不是它们,您只能将非NULL值排入队列。

void traverse(Node* root) {
    queue<Node*> q;

    // no tree no level order.
    if(root == NULL) {
        return;
    }

    // push the root to start with as we know it is not NULL.
    q.push(root);

    // loop till there are nodes in the queue.
    while(!q.empty()) {
        // dequeue the front node.
        Node *tmpNode = q.front();
        q.pop();

        // print it..we are sure it is not NULL.
        cout<<tmpNode->value<<" ";

        // enqueue left child if it exists.
        if(tmpNode->left) {
            q.push(tmpNode->left);
        }
        // enqueue right child if it exists.
        if(tmpNode->right) {
            q.push(tmpNode->right);
        }
    }
}

或者,如果您决定在队列中使用NULL,您可以执行以下操作:

void traverse(Node* root) {
    queue<Node*> q;

    // push the root..even if it is NULL.
    q.push(root);

    // loop till the queue is not empty.
    while(!q.empty()) {
        // dequeue the front node.
        Node *tmpNode = q.front();
        q.pop();

        // the dequeued pointer can be NULL or can point to a node.
        // process the node only if it is not NULL.     
        if(tmpNode) {       
            cout<<tmpNode->value<<" ";
            q.push(tmpNode->left);
            q.push(tmpNode->right);
        }
    }   
}

第一种方法是首选方法,因为一棵大树有很多NULL子节点(叶子节点的子节点),当我们以后只是不处理它们时,将它们排入队列是没有意义的。


1
投票

尝试:

void traverse(Node* root)
{
    queue<Node*> q;
    q.push(root);

    while(!q.empty())
    {
        Node* temp_node = q.front();
        q.pop();
        if (temp_node == NULL)
        {   continue;
        }

        cout << temp_node->value << endl;

        q.push(temp_node->left);
        q.push(temp_node->right);
   }
 }

1
投票

我认为上面的代码片段允许以数组格式打印级别顺序遍历。此代码可以帮助以级别顺序的形式编写解决方案。

vector<vector<int>> levelOrder(TreeNode* root) {
    vector<vector<int>> a ; 
    vector<int> b;
    if (root == NULL)   return a;
    std::queue<TreeNode *> q;
    q.push(root);
    int nodeCount ;
    TreeNode* temp;
    while(true){
        nodeCount = q.size();
        if (nodeCount == 0)    break;
        while(!nodeCount){
            temp = q.front();
            b.push_back(temp->val);
            q.pop();
            if(temp->left != NULL)    q.push(temp->left);
            if(temp->right!= NULL)    q.push(temp->right);
            nodeCount-- ;
        }
        a.push_back(b);
        b.resize(0);
    }
    return a;
}

输出:

[ [1],
  [2,3],
  [4,5]
]

0
投票

我的Java解决方案使用Queue数据结构和BFS算法:

   void levelOrder(Node root) {
        //LinkedList is class of Queue interface
        Queue<Node> queue=new LinkedList<>(); 
        queue.add(root); 

        //Using BFS algorithm and queue used in BFS solution
        while(!queue.isEmpty()) { 
                Node node=queue.poll(); 
                System.out.print(node.data+" "); 
                if(node.left!=null) 
                queue.add(node.left); 
                if(node.right!=null) 
                queue.add(node.right); 
              }
    }
© www.soinside.com 2019 - 2024. All rights reserved.