📌  相关文章
📜  通过将所有节点尽可能向右移动来修改二叉树

📅  最后修改于: 2021-09-06 06:46:12             🧑  作者: Mango

给定一棵二叉树,任务是打印将给定树的所有节点尽可能向右移动后获得的修改后的树的中序遍历,同时保持每个级别的相对顺序。
例子:

方法:解决给定问题的想法是使用堆栈从右到左存储一个级别的节点,使用队列存储下一个级别的现有节点,并使用 Level Order Traversal 在有效位置连接节点。请按照以下步骤解决问题:

  • 初始化一个栈S ,从右到左存储一棵二叉树的一层节点的序列。
  • 初始化一个队列Q来存储二叉树的某个级别的现有节点。
  • 如果 root 的右孩子存在,则将其推入队列Q 。腾出正确的孩子。
  • 如果 root 的左孩子存在,则将其推入队列Q 。腾出左孩子。
  • 推入堆栈S
  • 在二叉树上执行层序遍历,执行以下步骤:
    • 如果栈顶节点的右子节点是空的,则将队列前面的节点设置为右子节点。
    • 否则,对左孩子重复上述步骤。从栈顶弹出节点。
    • 将队列前面节点的左右子节点加入队列。
    • 在 Stack 中从右到左存储下一层的节点序列。
  • 完成上述步骤后,打印修改后的树的中序遍历。

下面是上述方法的实现:

C++14
// C++ program for the above approach
#include 
using namespace std;
 
// Structure of a Tree node
struct TreeNode {
    int val = 0;
    TreeNode* left;
    TreeNode* right;
 
    // Constructor
    TreeNode(int x)
    {
        val = x;
        left = right = NULL;
    }
};
 
// Function to print Inorder
// Traversal of a Binary Tree
void printTree(TreeNode* root)
{
    if (!root)
        return;
 
    // Traverse left child
    printTree(root->left);
 
    // Print current node
    cout << root->val << " ";
 
    // Traverse right child
    printTree(root->right);
}
 
// Function to shift all nodes of the
// given Binary Tree to as far as
// right possible
TreeNode* shiftRight(TreeNode* root)
{
 
    // If tree is empty
    if (!root)
        return NULL;
 
    stack st;
    queue q;
 
    // If right child exists
    if (root->right)
        q.push(root->right);
 
    root->right = NULL;
 
    // If left child exists
    if (root->left)
        q.push(root->left);
 
    root->left = NULL;
 
    // Push current node into stack
    st.push(root);
 
    while (!q.empty()) {
 
        // Count valid existing nodes
        // in current level
        int n = q.size();
        stack temp;
 
        // Iterate existing nodes
        // in the current level
        while (n--) {
 
            // If no right child exists
            if (!st.top()->right)
 
                // Set the rightmost
                // vacant node
                st.top()->right = q.front();
 
            // If no left child exists
            else {
 
                // Set rightmost vacant node
                st.top()->left = q.front();
 
                // Remove the node as both
                // child nodes are occupied
                st.pop();
            }
 
            // If r̥ight child exist
            if (q.front()->right)
 
                // Push into the queue
                q.push(q.front()->right);
 
            // Vacate right child
            q.front()->right = NULL;
 
            // If left child exists
            if (q.front()->left)
 
                // Push into the queue
                q.push(q.front()->left);
 
            // Vacate left child
            q.front()->left = NULL;
 
            // Add the node to stack to
            // maintain sequence of nodes
            // present in the level
            temp.push(q.front());
            q.pop();
        }
 
        while (!st.empty())
            st.pop();
 
        // Add nodes of the next
        // level into the stack st
        while (!temp.empty()) {
 
            st.push(temp.top());
            temp.pop();
        }
    }
 
    // Return the root of the
    // modified Tree
    return root;
}
 
// Driver Code
int main()
{
 
    TreeNode* root = new TreeNode(1);
    root->left = new TreeNode(2);
    root->right = new TreeNode(3);
    root->left->left = new TreeNode(4);
    root->left->right = new TreeNode(5);
    root->right->right = new TreeNode(6);
 
    // Function Call
    root = shiftRight(root);
 
    // Print the inOrder Traversal
    printTree(root);
 
    return 0;
}


Python3
# Python 3 program for the above approach
 
# Structure of a Tree node
class TreeNode:
 
    def __init__(self,val):
        self.val = val
        self.left = None
        self.right = None
 
# Function to print Inorder
# Traversal of a Binary Tree
def printTree(root):
    if (root == None):
        return
 
    # Traverse left child
    printTree(root.left)
 
    # Print current node
    print(root.val,end = " ")
 
    # Traverse right child
    printTree(root.right)
 
# Function to shift all nodes of the
# given Binary Tree to as far as
# right possible
def shiftRight(root):
   
    # If tree is empty
    if (root == None):
        return None
 
    st = []  #stack
    q = [] # queue
 
    # If right child exists
    if (root.right):
        q.append(root.right)
 
    root.right = None
 
    # If left child exists
    if (root.left):
        q.append(root.left)
 
    root.left = None
 
    # Push current node into stack
    st.append(root)
 
    while (len(q) > 0):
       
        # Count valid existing nodes
        # in current level
        n = len(q)
        temp = []
 
        # Iterate existing nodes
        # in the current level
        while (n > 0 and len(st) > 0 and len(q) > 0):
           
            # If no right child exists
            if (st[len(st) - 1].right == None):
 
                # Set the rightmost
                # vacant node
                st[len(st) - 1].right = q[0]
 
            # If no left child exists
            else:
               
                # Set rightmost vacant node
                st[len(st) - 1].left = q[0]
 
                # Remove the node as both
                # child nodes are occupied
                st = st[:-1]
 
            # If r̥ight child exist
            if (q[0].right):
               
                # Push into the queue
                q.append(q[0].right)
 
            # Vacate right child
            q[0].right = None
 
            # If left child exists
            if (q[0].left):
 
                # Push into the queue
                q.append(q[0].left)
 
            # Vacate left child
            q[0].left = None
 
            # Add the node to stack to
            # maintain sequence of nodes
            # present in the level
            temp.append(q[0])
            q = q[1:]
 
        while (len(st) > 0):
            st = st[:-1]
 
        # Add nodes of the next
        # level into the stack st
        while(len(temp)>0):
            st.append(temp[len(temp)-1])
            temp = temp[:-1]
 
    # Return the root of the
    # modified Tree
    return root
 
# Driver Code
if __name__ == '__main__':
    root = TreeNode(1)
    root.left = TreeNode(2)
    root.right = TreeNode(3)
    root.left.left = TreeNode(4)
    root.left.right = TreeNode(5)
    root.right.right = TreeNode(6)
 
    # Function Call
    root = shiftRight(root)
 
    # Print the inOrder Traversal
    printTree(root)
     
    # This code is contributed by SURENDRA_GANGWAR.


C++
// CPP program for the above approach
#include 
#include 
using namespace std;
 
// Structure of a Tree node
struct TreeNode {
    int val = 0;
    TreeNode* left;
    TreeNode* right;
 
    // Constructor
    TreeNode(int x)
    {
        val = x;
        left = right = NULL;
    }
};
 
// Function to print Inorder
// Traversal of a Binary Tree
void printTree(TreeNode* root)
{
    if (!root)
        return;
 
    // Traverse left child
    printTree(root->left);
 
    // Print current node
    cout << root->val << " ";
 
    // Traverse right child
    printTree(root->right);
}
 
void dfsit(TreeNode* rt, int key,
           map >& mp)
{
    if (!rt) {
        return;
    }
    mp[key].push_back(rt);
    dfsit(rt->right, key + 1, mp);
    dfsit(rt->left, key + 1, mp);
    rt->left = NULL;
    rt->right = NULL;
}
 
TreeNode* shiftRight(TreeNode* root)
{
    TreeNode* tmp = root;
    map > mp;
    int i = 0;
 
    dfsit(root, 0, mp);
    int n = mp.size();
    TreeNode* cur = new TreeNode(-1);
   
  
    queue st;
    st.push(cur);
 
  while (i < n) {
        vector nd = mp[i];
        int j = 0;
        queue tmp;
        while (j < nd.size()) {
            auto r = st.front();
            st.pop();
            r->right = nd[j];
            tmp.push(nd[j]);
            j++;
            if (j < nd.size()) {
                r->left = nd[j];
                tmp.push(nd[j]);
                j++;
            }
        }
        st = tmp;
        i++;
    }
 
    return cur->right;
}
 
// Driver Code
int main()
{
 
    TreeNode* root = new TreeNode(1);
    root->left = new TreeNode(2);
    root->right = new TreeNode(3);
    root->left->left = new TreeNode(4);
    root->left->right = new TreeNode(5);
    root->right->right = new TreeNode(6);
 
    // Function Call
    root = shiftRight(root);
 
    // Print the inOrder Traversal
    printTree(root);
    return 0;
}


输出
2 4 1 5 3 6 

时间复杂度: O(N)
辅助空间: O(N)

方法二:(使用hashmap)
1. 存储层级和对应的树节点。
2.然后贪婪地将节点首先分配为右孩子,然后以2对的形式分配给左孩子。

C++

// CPP program for the above approach
#include 
#include 
using namespace std;
 
// Structure of a Tree node
struct TreeNode {
    int val = 0;
    TreeNode* left;
    TreeNode* right;
 
    // Constructor
    TreeNode(int x)
    {
        val = x;
        left = right = NULL;
    }
};
 
// Function to print Inorder
// Traversal of a Binary Tree
void printTree(TreeNode* root)
{
    if (!root)
        return;
 
    // Traverse left child
    printTree(root->left);
 
    // Print current node
    cout << root->val << " ";
 
    // Traverse right child
    printTree(root->right);
}
 
void dfsit(TreeNode* rt, int key,
           map >& mp)
{
    if (!rt) {
        return;
    }
    mp[key].push_back(rt);
    dfsit(rt->right, key + 1, mp);
    dfsit(rt->left, key + 1, mp);
    rt->left = NULL;
    rt->right = NULL;
}
 
TreeNode* shiftRight(TreeNode* root)
{
    TreeNode* tmp = root;
    map > mp;
    int i = 0;
 
    dfsit(root, 0, mp);
    int n = mp.size();
    TreeNode* cur = new TreeNode(-1);
   
  
    queue st;
    st.push(cur);
 
  while (i < n) {
        vector nd = mp[i];
        int j = 0;
        queue tmp;
        while (j < nd.size()) {
            auto r = st.front();
            st.pop();
            r->right = nd[j];
            tmp.push(nd[j]);
            j++;
            if (j < nd.size()) {
                r->left = nd[j];
                tmp.push(nd[j]);
                j++;
            }
        }
        st = tmp;
        i++;
    }
 
    return cur->right;
}
 
// Driver Code
int main()
{
 
    TreeNode* root = new TreeNode(1);
    root->left = new TreeNode(2);
    root->right = new TreeNode(3);
    root->left->left = new TreeNode(4);
    root->left->right = new TreeNode(5);
    root->right->right = new TreeNode(6);
 
    // Function Call
    root = shiftRight(root);
 
    // Print the inOrder Traversal
    printTree(root);
    return 0;
}
输出
2 4 1 5 3 6 

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live