📌  相关文章
📜  修改二叉树以仅使用右指针获取前序遍历

📅  最后修改于: 2022-05-13 01:57:09.415000             🧑  作者: Mango

修改二叉树以仅使用右指针获取前序遍历

给定一棵二叉树。以这样的方式修改它,以便在修改后您可以只使用正确的指针对其进行前序遍历。在修改期间,您可以使用右指针和左指针。
例子:

Input :    10
          /   \
        8      2
      /  \    
    3     5  
Output :    10
              \
               8
                \ 
                 3
                  \
                   5
                    \
                     2
Explanation : The preorder traversal
of given binary tree is 10 8 3 5 2.

方法1(递归)
需要使根的右指针指向左子树。
如果节点刚刚离开了孩子,那么只需将孩子向右移动即可完成对该节点的处理。
如果也有一个右孩子,那么它应该成为原始左子树最右边的右孩子。
代码中使用的上述函数处理一个节点,然后返回转换后的子树的最右边的节点。

C++
// C code to modify binary tree for
// traversal using only right pointer
#include 
 
using namespace std;
 
// A binary tree node has data,
// left child and right child
struct Node {
    int data;
    struct Node* left;
    struct Node* right;
};
 
// function that allocates a new node
// with the given data and NULL left
// and right pointers.
struct Node* newNode(int data)
{
    struct Node* node = new struct Node;
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    return (node);
}
 
// Function to modify tree
struct Node* modifytree(struct Node* root)
{
    struct Node* right = root->right;
    struct Node* rightMost = root;
 
    // if the left tree exists
    if (root->left) {
 
        // get the right-most of the
        // original left subtree
        rightMost = modifytree(root->left);
 
        // set root right to left subtree
        root->right = root->left;
        root->left = NULL;
    }
 
    // if the right subtree does
    // not exists we are done!
    if (!right)
        return rightMost;
 
    // set right pointer of right-most
    // of the original left subtree
    rightMost->right = right;
 
    // modify the rightsubtree
    rightMost = modifytree(right);
    return rightMost;
}
 
// printing using right pointer only
void printpre(struct Node* root)
{
    while (root != NULL) {
        cout << root->data << " ";
        root = root->right;
    }
}
 
// Driver program to test above functions
int main()
{
    /* Constructed binary tree is
         10
        / \
       8   2
      / \ 
     3   5     */
    struct Node* root = newNode(10);
    root->left = newNode(8);
    root->right = newNode(2);
    root->left->left = newNode(3);
    root->left->right = newNode(5);
 
    modifytree(root);
    printpre(root);
 
    return 0;
}


Java
// Java code to modify binary tree for
// traversal using only right pointer
class GFG
{
 
// A binary tree node has data,
// left child and right child
static class Node
{
    int data;
    Node left;
    Node right;
};
 
// function that allocates a new node
// with the given data and null left
// and right pointers.
static Node newNode(int data)
{
    Node node = new Node();
    node.data = data;
    node.left = null;
    node.right = null;
    return (node);
}
 
// Function to modify tree
static Node modifytree( Node root)
{
    Node right = root.right;
    Node rightMost = root;
 
    // if the left tree exists
    if (root.left != null)
    {
 
        // get the right-most of the
        // original left subtree
        rightMost = modifytree(root.left);
 
        // set root right to left subtree
        root.right = root.left;
        root.left = null;
    }
 
    // if the right subtree does
    // not exists we are done!
    if (right == null)
        return rightMost;
 
    // set right pointer of right-most
    // of the original left subtree
    rightMost.right = right;
 
    // modify the rightsubtree
    rightMost = modifytree(right);
    return rightMost;
}
 
// printing using right pointer only
static void printpre( Node root)
{
    while (root != null)
    {
        System.out.print( root.data + " ");
        root = root.right;
    }
}
 
// Driver cde
public static void main(String args[])
{
    /* Constructed binary tree is
        10
        / \
    8 2
    / \
    3 5 */
    Node root = newNode(10);
    root.left = newNode(8);
    root.right = newNode(2);
    root.left.left = newNode(3);
    root.left.right = newNode(5);
 
    modifytree(root);
    printpre(root);
}
}
 
// This code is contributed by Arnab Kundu


Python3
# Python code to modify binary tree for
# traversal using only right pointer
 
class newNode():
 
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
         
         
# Function to modify tree
def modifytree(root):
 
    right = root.right
    rightMost = root
 
    # if the left tree exists
    if (root.left):
 
        # get the right-most of the
        # original left subtree
        rightMost = modifytree(root.left)
 
        # set root right to left subtree
        root.right = root.left
        root.left = None
     
 
    # if the right subtree does
    # not exists we are done!
    if (not right):
        return rightMost
 
    # set right pointer of right-most
    # of the original left subtree
    rightMost.right = right
 
    # modify the rightsubtree
    rightMost = modifytree(right)
    return rightMost
 
 
# printing using right pointer only
def printpre(root):
 
    while (root != None):
        print(root.data,end=" ")
        root = root.right
         
# Driver code
if __name__ == '__main__':
    """ Constructed binary tree is
    10
        / \
    8 2
    / \
    3 5     """
    root = newNode(10)
    root.left = newNode(8)
    root.right = newNode(2)
    root.left.left = newNode(3)
    root.left.right = newNode(5)
 
    modifytree(root)
    printpre(root)
 
# This code is contributed by SHUBHAMSINGH10


C#
// C# code to modify binary tree for
// traversal using only right pointer
using System;
     
class GFG
{
 
// A binary tree node has data,
// left child and right child
public class Node
{
    public int data;
    public Node left;
    public Node right;
};
 
// function that allocates a new node
// with the given data and null left
// and right pointers.
static Node newNode(int data)
{
    Node node = new Node();
    node.data = data;
    node.left = null;
    node.right = null;
    return (node);
}
 
// Function to modify tree
static Node modifytree( Node root)
{
    Node right = root.right;
    Node rightMost = root;
 
    // if the left tree exists
    if (root.left != null)
    {
 
        // get the right-most of the
        // original left subtree
        rightMost = modifytree(root.left);
 
        // set root right to left subtree
        root.right = root.left;
        root.left = null;
    }
 
    // if the right subtree does
    // not exists we are done!
    if (right == null)
        return rightMost;
 
    // set right pointer of right-most
    // of the original left subtree
    rightMost.right = right;
 
    // modify the rightsubtree
    rightMost = modifytree(right);
    return rightMost;
}
 
// printing using right pointer only
static void printpre( Node root)
{
    while (root != null)
    {
        Console.Write( root.data + " ");
        root = root.right;
    }
}
 
// Driver cde
public static void Main(String []args)
{
    /* Constructed binary tree is
        10
        / \
    8 2
    / \
    3 5 */
    Node root = newNode(10);
    root.left = newNode(8);
    root.right = newNode(2);
    root.left.left = newNode(3);
    root.left.right = newNode(5);
 
    modifytree(root);
    printpre(root);
}
}
 
// This code is contributed by 29AjayKumar


Javascript


C++
// C++ code to modify binary tree for
// traversal using only right pointer
#include 
#include 
#include 
#include 
 
using namespace std;
 
// A binary tree node has data,
// left child and right child
struct Node {
    int data;
    struct Node* left;
    struct Node* right;
};
 
// Helper function that allocates a new
// node with the given data and NULL
// left and right  pointers.
struct Node* newNode(int data)
{
    struct Node* node = new struct Node;
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    return (node);
}
 
// An iterative process to set the right
// pointer of Binary tree
void modifytree(struct Node* root)
{
    // Base Case
    if (root == NULL)
        return;
 
    // Create an empty stack and push root to it
    stack nodeStack;
    nodeStack.push(root);
 
    /* Pop all items one by one.
        Do following for every popped item
       a) print it
       b) push its right child
       c) push its left child
    Note that right child is pushed first
    so that left is processed first */
    struct Node* pre = NULL;
    while (nodeStack.empty() == false) {
 
        // Pop the top item from stack
        struct Node* node = nodeStack.top();
 
        nodeStack.pop();
 
        // Push right and left children of
        // the popped node to stack
        if (node->right)
            nodeStack.push(node->right);
        if (node->left)
            nodeStack.push(node->left);
 
        // check if some previous node exists
        if (pre != NULL) {
 
            // set the right pointer of
            // previous node to current
            pre->right = node;
        }
 
        // set previous node as current node
        pre = node;
    }
}
 
// printing using right pointer only
void printpre(struct Node* root)
{
    while (root != NULL) {
        cout << root->data << " ";
        root = root->right;
    }
}
 
// Driver code
int main()
{
    /* Constructed binary tree is
            10
          /   \
        8      2
      /  \   
    3     5 
  */
    struct Node* root = newNode(10);
    root->left = newNode(8);
    root->right = newNode(2);
    root->left->left = newNode(3);
    root->left->right = newNode(5);
 
    modifytree(root);
    printpre(root);
 
    return 0;
}


Java
// Java code to modify binary tree for
// traversal using only right pointer
import java.util.*;
class GfG {
 
// A binary tree node has data,
// left child and right child
static class Node {
    int data;
    Node left;
    Node right;
}
 
// Helper function that allocates a new
// node with the given data and NULL
// left and right pointers.
static Node newNode(int data)
{
    Node node = new Node();
    node.data = data;
    node.left = null;
    node.right = null;
    return (node);
}
 
// An iterative process to set the right
// pointer of Binary tree
static void modifytree(Node root)
{
    // Base Case
    if (root == null)
        return;
 
    // Create an empty stack and push root to it
    Stack nodeStack = new Stack ();
    nodeStack.push(root);
 
    /* Pop all items one by one.
        Do following for every popped item
    a) print it
    b) push its right child
    c) push its left child
    Note that right child is pushed first
    so that left is processed first */
    Node pre = null;
    while (nodeStack.isEmpty() == false) {
 
        // Pop the top item from stack
        Node node = nodeStack.peek();
 
        nodeStack.pop();
 
        // Push right and left children of
        // the popped node to stack
        if (node.right != null)
            nodeStack.push(node.right);
        if (node.left != null)
            nodeStack.push(node.left);
 
        // check if some previous node exists
        if (pre != null) {
 
            // set the right pointer of
            // previous node to current
            pre.right = node;
        }
 
        // set previous node as current node
        pre = node;
    }
}
 
// printing using right pointer only
static void printpre(Node root)
{
    while (root != null) {
        System.out.print(root.data + " ");
        root = root.right;
    }
}
 
// Driver code
public static void main(String[] args)
{
    /* Constructed binary tree is
            10
        / \
        8     2
    / \    
    3     5
*/
    Node root = newNode(10);
    root.left = newNode(8);
    root.right = newNode(2);
    root.left.left = newNode(3);
    root.left.right = newNode(5);
 
    modifytree(root);
    printpre(root);
 
}
}


Python
# Python code to modify binary tree for
# traversal using only right pointer
 
# A binary tree node has data,
# left child and right child
class newNode():
 
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# An iterative process to set the right
# pointer of Binary tree
def modifytree( root):
     
    # Base Case
    if (root == None):
        return
         
    # Create an empty stack and append root to it
    nodeStack = []
    nodeStack.append(root)
     
    ''' Pop all items one by one.
    Do following for every popped item
    a) print
    b) append its right child
    c) append its left child
    Note that right child is appended first
    so that left is processed first '''
    pre = None
    while (len(nodeStack)):
         
        # Pop the top item from stack
        node = nodeStack[-1]
        nodeStack.pop()
         
        # append right and left children of
        # the popped node to stack
        if (node.right):
            nodeStack.append(node.right)
        if (node.left):
            nodeStack.append(node.left)
             
        # check if some previous node exists
        if (pre != None):
             
            # set the right pointer of
            # previous node to current
            pre.right = node
             
        # set previous node as current node
        pre = node
         
# printing using right pointer only
def printpre( root):
    while (root != None):
        print(root.data, end = " ")
        root = root.right
     
# Driver code
 
''' Constructed binary tree is
        10
    / \
    8     2
/ \    
3     5
'''
root = newNode(10)
root.left = newNode(8)
root.right = newNode(2)
root.left.left = newNode(3)
root.left.right = newNode(5)
 
modifytree(root)
printpre(root)
 
# This code is contributed by SHUBHAMSINGH10


C#
// C# code to modify binary tree for
// traversal using only right pointer
using System;
using System.Collections;
 
class GfG
{
 
// A binary tree node has data,
// left child and right child
public class Node
{
    public int data;
    public Node left;
    public Node right;
}
 
// Helper function that allocates a new
// node with the given data and NULL
// left and right pointers.
static Node newNode(int data)
{
    Node node = new Node();
    node.data = data;
    node.left = null;
    node.right = null;
    return (node);
}
 
// An iterative process to set the right
// pointer of Binary tree
static void modifytree(Node root)
{
    // Base Case
    if (root == null)
        return;
 
    // Create an empty stack and Push root to it
    Stack nodeStack = new Stack();
    nodeStack.Push(root);
 
    /* Pop all items one by one.
        Do following for every Popped item
    a) print it
    b) Push its right child
    c) Push its left child
    Note that right child is Pushed first
    so that left is processed first */
    Node pre = null;
    while (nodeStack.Count !=0)
    {
 
        // Pop the top item from stack
        Node node = (Node)nodeStack.Peek();
 
        nodeStack.Pop();
 
        // Push right and left children of
        // the Popped node to stack
        if (node.right != null)
            nodeStack.Push(node.right);
        if (node.left != null)
            nodeStack.Push(node.left);
 
        // check if some previous node exists
        if (pre != null)
        {
 
            // set the right pointer of
            // previous node to current
            pre.right = node;
        }
 
        // set previous node as current node
        pre = node;
    }
}
 
// printing using right pointer only
static void printpre(Node root)
{
    while (root != null)
    {
        Console.Write(root.data + " ");
        root = root.right;
    }
}
 
// Driver code
public static void Main(String []args)
{
    /* Constructed binary tree is
            10
        / \
        8     2
    / \    
    3     5
*/
    Node root = newNode(10);
    root.left = newNode(8);
    root.right = newNode(2);
    root.left.left = newNode(3);
    root.left.right = newNode(5);
 
    modifytree(root);
    printpre(root);
}
}
 
// This code is contributed by
// Arnab Kundu


Javascript


输出:
10 8 3 5 2 

方法2(迭代)
这可以使用迭代前序遍历轻松完成。看这里。迭代前序遍历
这个想法是维护一个变量prev,它维护前序遍历的前一个节点。每次遇到新节点时,该节点将其权限设置为前一个节点,并且 prev 等于当前节点。最后,我们将得到一种链表,其第一个元素是根元素,然后是左子元素,然后是右元素,以此类推。

C++

// C++ code to modify binary tree for
// traversal using only right pointer
#include 
#include 
#include 
#include 
 
using namespace std;
 
// A binary tree node has data,
// left child and right child
struct Node {
    int data;
    struct Node* left;
    struct Node* right;
};
 
// Helper function that allocates a new
// node with the given data and NULL
// left and right  pointers.
struct Node* newNode(int data)
{
    struct Node* node = new struct Node;
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    return (node);
}
 
// An iterative process to set the right
// pointer of Binary tree
void modifytree(struct Node* root)
{
    // Base Case
    if (root == NULL)
        return;
 
    // Create an empty stack and push root to it
    stack nodeStack;
    nodeStack.push(root);
 
    /* Pop all items one by one.
        Do following for every popped item
       a) print it
       b) push its right child
       c) push its left child
    Note that right child is pushed first
    so that left is processed first */
    struct Node* pre = NULL;
    while (nodeStack.empty() == false) {
 
        // Pop the top item from stack
        struct Node* node = nodeStack.top();
 
        nodeStack.pop();
 
        // Push right and left children of
        // the popped node to stack
        if (node->right)
            nodeStack.push(node->right);
        if (node->left)
            nodeStack.push(node->left);
 
        // check if some previous node exists
        if (pre != NULL) {
 
            // set the right pointer of
            // previous node to current
            pre->right = node;
        }
 
        // set previous node as current node
        pre = node;
    }
}
 
// printing using right pointer only
void printpre(struct Node* root)
{
    while (root != NULL) {
        cout << root->data << " ";
        root = root->right;
    }
}
 
// Driver code
int main()
{
    /* Constructed binary tree is
            10
          /   \
        8      2
      /  \   
    3     5 
  */
    struct Node* root = newNode(10);
    root->left = newNode(8);
    root->right = newNode(2);
    root->left->left = newNode(3);
    root->left->right = newNode(5);
 
    modifytree(root);
    printpre(root);
 
    return 0;
}

Java

// Java code to modify binary tree for
// traversal using only right pointer
import java.util.*;
class GfG {
 
// A binary tree node has data,
// left child and right child
static class Node {
    int data;
    Node left;
    Node right;
}
 
// Helper function that allocates a new
// node with the given data and NULL
// left and right pointers.
static Node newNode(int data)
{
    Node node = new Node();
    node.data = data;
    node.left = null;
    node.right = null;
    return (node);
}
 
// An iterative process to set the right
// pointer of Binary tree
static void modifytree(Node root)
{
    // Base Case
    if (root == null)
        return;
 
    // Create an empty stack and push root to it
    Stack nodeStack = new Stack ();
    nodeStack.push(root);
 
    /* Pop all items one by one.
        Do following for every popped item
    a) print it
    b) push its right child
    c) push its left child
    Note that right child is pushed first
    so that left is processed first */
    Node pre = null;
    while (nodeStack.isEmpty() == false) {
 
        // Pop the top item from stack
        Node node = nodeStack.peek();
 
        nodeStack.pop();
 
        // Push right and left children of
        // the popped node to stack
        if (node.right != null)
            nodeStack.push(node.right);
        if (node.left != null)
            nodeStack.push(node.left);
 
        // check if some previous node exists
        if (pre != null) {
 
            // set the right pointer of
            // previous node to current
            pre.right = node;
        }
 
        // set previous node as current node
        pre = node;
    }
}
 
// printing using right pointer only
static void printpre(Node root)
{
    while (root != null) {
        System.out.print(root.data + " ");
        root = root.right;
    }
}
 
// Driver code
public static void main(String[] args)
{
    /* Constructed binary tree is
            10
        / \
        8     2
    / \    
    3     5
*/
    Node root = newNode(10);
    root.left = newNode(8);
    root.right = newNode(2);
    root.left.left = newNode(3);
    root.left.right = newNode(5);
 
    modifytree(root);
    printpre(root);
 
}
}

Python

# Python code to modify binary tree for
# traversal using only right pointer
 
# A binary tree node has data,
# left child and right child
class newNode():
 
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# An iterative process to set the right
# pointer of Binary tree
def modifytree( root):
     
    # Base Case
    if (root == None):
        return
         
    # Create an empty stack and append root to it
    nodeStack = []
    nodeStack.append(root)
     
    ''' Pop all items one by one.
    Do following for every popped item
    a) print
    b) append its right child
    c) append its left child
    Note that right child is appended first
    so that left is processed first '''
    pre = None
    while (len(nodeStack)):
         
        # Pop the top item from stack
        node = nodeStack[-1]
        nodeStack.pop()
         
        # append right and left children of
        # the popped node to stack
        if (node.right):
            nodeStack.append(node.right)
        if (node.left):
            nodeStack.append(node.left)
             
        # check if some previous node exists
        if (pre != None):
             
            # set the right pointer of
            # previous node to current
            pre.right = node
             
        # set previous node as current node
        pre = node
         
# printing using right pointer only
def printpre( root):
    while (root != None):
        print(root.data, end = " ")
        root = root.right
     
# Driver code
 
''' Constructed binary tree is
        10
    / \
    8     2
/ \    
3     5
'''
root = newNode(10)
root.left = newNode(8)
root.right = newNode(2)
root.left.left = newNode(3)
root.left.right = newNode(5)
 
modifytree(root)
printpre(root)
 
# This code is contributed by SHUBHAMSINGH10

C#

// C# code to modify binary tree for
// traversal using only right pointer
using System;
using System.Collections;
 
class GfG
{
 
// A binary tree node has data,
// left child and right child
public class Node
{
    public int data;
    public Node left;
    public Node right;
}
 
// Helper function that allocates a new
// node with the given data and NULL
// left and right pointers.
static Node newNode(int data)
{
    Node node = new Node();
    node.data = data;
    node.left = null;
    node.right = null;
    return (node);
}
 
// An iterative process to set the right
// pointer of Binary tree
static void modifytree(Node root)
{
    // Base Case
    if (root == null)
        return;
 
    // Create an empty stack and Push root to it
    Stack nodeStack = new Stack();
    nodeStack.Push(root);
 
    /* Pop all items one by one.
        Do following for every Popped item
    a) print it
    b) Push its right child
    c) Push its left child
    Note that right child is Pushed first
    so that left is processed first */
    Node pre = null;
    while (nodeStack.Count !=0)
    {
 
        // Pop the top item from stack
        Node node = (Node)nodeStack.Peek();
 
        nodeStack.Pop();
 
        // Push right and left children of
        // the Popped node to stack
        if (node.right != null)
            nodeStack.Push(node.right);
        if (node.left != null)
            nodeStack.Push(node.left);
 
        // check if some previous node exists
        if (pre != null)
        {
 
            // set the right pointer of
            // previous node to current
            pre.right = node;
        }
 
        // set previous node as current node
        pre = node;
    }
}
 
// printing using right pointer only
static void printpre(Node root)
{
    while (root != null)
    {
        Console.Write(root.data + " ");
        root = root.right;
    }
}
 
// Driver code
public static void Main(String []args)
{
    /* Constructed binary tree is
            10
        / \
        8     2
    / \    
    3     5
*/
    Node root = newNode(10);
    root.left = newNode(8);
    root.right = newNode(2);
    root.left.left = newNode(3);
    root.left.right = newNode(5);
 
    modifytree(root);
    printpre(root);
}
}
 
// This code is contributed by
// Arnab Kundu

Javascript


输出:
10 8 3 5 2