📜  将二叉树转换为线程二叉树 |第 2 组(高效)

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

将二叉树转换为线程二叉树 |第 2 组(高效)

线程二叉树的思想是使中序遍历更快,并且没有堆栈,没有递归。在简单的线程二叉树中,NULL 右指针用于存储中序后继。无论何时右指针为 NULL,它都用于存储中序后继。
下图显示了一个示例单线程二叉树。虚线代表线程。

螺纹BT

以下是单线程二叉树的结构。

C
struct Node
{
    int key;
    Node *left, *right;
 
    // Used to indicate whether the right pointer is a normal right
    // pointer or a pointer to inorder successor.
    bool isThreaded;
};


Java
static class Node
{
    int key;
    Node left, right;
 
    // Used to indicate whether the right pointer is a normal right
    // pointer or a pointer to inorder successor.
    boolean isThreaded;
};
 
// This code is contributed by umadevi9616


Python3
class Node:
    def __init__(self, data):
        self.key = data;
        self.left = none;
        self.right = none;
        self.isThreaded = false;
    # Used to indicate whether the right pointer is a normal right
    # pointer or a pointer to inorder successor.
 
# This code is contributed by umadevi9616


C#
public class Node {
    public int key;
    public Node left, right;
 
    // Used to indicate whether the right pointer is a normal right
    // pointer or a pointer to inorder successor.
    public bool isThreaded;
};
 
 
// This code is contributed by umadevi9616


Javascript
/* structure of a node in threaded binary tree */
 class Node {
        constructor(val) {
            this.data = val;
            this.left = null;
            this.right = null;
     
   
    // Used to indicate whether the right pointer
    // is a normal right pointer or a pointer
    // to inorder successor.
    this.isThreaded = false;
    }
    }
     
    // This code is contributed by famously.


C++
/* C++ program to convert a Binary Tree to
    Threaded Tree */
#include 
using namespace std;
 
/* Structure of a node in threaded binary tree */
struct Node
{
    int key;
    Node *left, *right;
 
    // Used to indicate whether the right pointer
    // is a normal right pointer or a pointer
    // to inorder successor.
    bool isThreaded;
};
 
// Converts tree with given root to threaded
// binary tree.
// This function returns rightmost child of
// root.
Node *createThreaded(Node *root)
{
    // Base cases : Tree is empty or has single
    //              node
    if (root == NULL)
        return NULL;
    if (root->left == NULL &&
        root->right == NULL)
        return root;
 
    // Find predecessor if it exists
    if (root->left != NULL)
    {
        // Find predecessor of root (Rightmost
        // child in left subtree)
        Node* l = createThreaded(root->left);
 
        // Link a thread from predecessor to
        // root.
        l->right = root;
        l->isThreaded = true;
    }
 
    // If current node is rightmost child
    if (root->right == NULL)
        return root;
 
    // Recur for right subtree.
    return createThreaded(root->right);
}
 
// A utility function to find leftmost node
// in a binary tree rooted with 'root'.
// This function is used in inOrder()
Node *leftMost(Node *root)
{
    while (root != NULL && root->left != NULL)
        root = root->left;
    return root;
}
 
// Function to do inorder traversal of a threadded
// binary tree
void inOrder(Node *root)
{
    if (root == NULL) return;
 
    // Find the leftmost node in Binary Tree
    Node *cur = leftMost(root);
 
    while (cur != NULL)
    {
        cout << cur->key << " ";
 
        // If this Node is a thread Node, then go to
        // inorder successor
        if (cur->isThreaded)
            cur = cur->right;
 
        else // Else go to the leftmost child in right subtree
            cur = leftMost(cur->right);
    }
}
 
// A utility function to create a new node
Node *newNode(int key)
{
    Node *temp = new Node;
    temp->left = temp->right = NULL;
    temp->key = key;
    return temp;
}
 
// Driver program to test above functions
int main()
{
    /*       1
            / \
           2   3
          / \ / \
         4  5 6  7   */
    Node *root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    root->right->left = newNode(6);
    root->right->right = newNode(7);
 
    createThreaded(root);
 
    cout << "Inorder traversal of created "
            "threaded tree is\n";
    inOrder(root);
    return 0;
}


Java
/* Java program to convert a Binary Tree to
    Threaded Tree */
import java.util.*;
class solution
{
  
   
/* structure of a node in threaded binary tree */
static class Node
{
    int key;
    Node left, right;
   
    // Used to indicate whether the right pointer
    // is a normal right pointer or a pointer
    // to inorder successor.
    boolean isThreaded;
};
   
// Converts tree with given root to threaded
// binary tree.
// This function returns rightmost child of
// root.
static Node createThreaded(Node root)
{
    // Base cases : Tree is empty or has single
    //              node
    if (root == null)
        return null;
    if (root.left == null &&
        root.right == null)
        return root;
   
    // Find predecessor if it exists
    if (root.left != null)
    {
        // Find predecessor of root (Rightmost
        // child in left subtree)
        Node l = createThreaded(root.left);
   
        // Link a thread from predecessor to
        // root.
        l.right = root;
        l.isThreaded = true;
    }
   
    // If current node is rightmost child
    if (root.right == null)
        return root;
   
    // Recur for right subtree.
    return createThreaded(root.right);
}
   
// A utility function to find leftmost node
// in a binary tree rooted with 'root'.
// This function is used in inOrder()
static Node leftMost(Node root)
{
    while (root != null && root.left != null)
        root = root.left;
    return root;
}
   
// Function to do inorder traversal of a threadded
// binary tree
static void inOrder(Node root)
{
    if (root == null) return;
   
    // Find the leftmost node in Binary Tree
    Node cur = leftMost(root);
   
    while (cur != null)
    {
        System.out.print(cur.key + " ");
   
        // If this Node is a thread Node, then go to
        // inorder successor
        if (cur.isThreaded)
            cur = cur.right;
   
        else // Else go to the leftmost child in right subtree
            cur = leftMost(cur.right);
    }
}
   
// A utility function to create a new node
static Node newNode(int key)
{
    Node temp = new Node();
    temp.left = temp.right = null;
    temp.key = key;
    return temp;
}
   
// Driver program to test above functions
public static void main(String args[])
{
   /*       1
            / \
           2   3
          / \ / \
         4  5 6  7   */
    Node root = newNode(1);
    root.left = newNode(2);
    root.right = newNode(3);
    root.left.left = newNode(4);
    root.left.right = newNode(5);
    root.right.left = newNode(6);
    root.right.right = newNode(7);
   
    createThreaded(root);
   
    System.out.println("Inorder traversal of created "+"threaded tree is\n");
    inOrder(root); 
}
}
//contributed by Arnab Kundu


Python3
# Python3 program to convert a Binary Tree to
# Threaded Tree
 
# A utility function to create a new node
class newNode:
    def __init__(self, key):
        self.left = self.right = None
        self.key = key
        self.isThreaded = None
         
# Converts tree with given root to threaded
# binary tree.
# This function returns rightmost child of
# root.
def createThreaded(root):
     
    # Base cases : Tree is empty or has 
    #               single node
    if root == None:
        return None
    if root.left == None and root.right == None:
        return root
 
    # Find predecessor if it exists
    if root.left != None:
         
        # Find predecessor of root (Rightmost
        # child in left subtree)
        l = createThreaded(root.left)
 
        # Link a thread from predecessor
        # to root.
        l.right = root
        l.isThreaded = True
 
    # If current node is rightmost child
    if root.right == None:
        return root
 
    # Recur for right subtree.
    return createThreaded(root.right)
 
# A utility function to find leftmost node
# in a binary tree rooted with 'root'.
# This function is used in inOrder()
def leftMost(root):
    while root != None and root.left != None:
        root = root.left
    return root
 
# Function to do inorder traversal of a
# threaded binary tree
def inOrder(root):
    if root == None:
        return
 
    # Find the leftmost node in Binary Tree
    cur = leftMost(root)
 
    while cur != None:
        print(cur.key, end = " ")
 
        # If this Node is a thread Node, then
        # go to inorder successor
        if cur.isThreaded:
            cur = cur.right
 
        else: # Else go to the leftmost child
              # in right subtree
            cur = leftMost(cur.right)
 
# Driver Code
if __name__ == '__main__':
     
    #         1
    #     / \
    #     2 3
    #     / \ / \
    #     4 5 6 7
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
    root.left.left = newNode(4)
    root.left.right = newNode(5)
    root.right.left = newNode(6)
    root.right.right = newNode(7)
 
    createThreaded(root)
 
    print("Inorder traversal of created",
                      "threaded tree is")
    inOrder(root)
 
# This code is contributed by PranchalK


C#
using System;
 
/* C# program to convert a Binary Tree to 
    Threaded Tree */
public class solution
{
 
 
/* structure of a node in threaded binary tree */
public class Node
{
    public int key;
    public Node left, right;
 
    // Used to indicate whether the right pointer 
    // is a normal right pointer or a pointer 
    // to inorder successor. 
    public bool isThreaded;
}
 
// Converts tree with given root to threaded 
// binary tree. 
// This function returns rightmost child of 
// root. 
public static Node createThreaded(Node root)
{
    // Base cases : Tree is empty or has single 
    //              node 
    if (root == null)
    {
        return null;
    }
    if (root.left == null && root.right == null)
    {
        return root;
    }
 
    // Find predecessor if it exists 
    if (root.left != null)
    {
        // Find predecessor of root (Rightmost 
        // child in left subtree) 
        Node l = createThreaded(root.left);
 
        // Link a thread from predecessor to 
        // root. 
        l.right = root;
        l.isThreaded = true;
    }
 
    // If current node is rightmost child 
    if (root.right == null)
    {
        return root;
    }
 
    // Recur for right subtree. 
    return createThreaded(root.right);
}
 
// A utility function to find leftmost node 
// in a binary tree rooted with 'root'. 
// This function is used in inOrder() 
public static Node leftMost(Node root)
{
    while (root != null && root.left != null)
    {
        root = root.left;
    }
    return root;
}
 
// Function to do inorder traversal of a threadded 
// binary tree 
public static void inOrder(Node root)
{
    if (root == null)
    {
        return;
    }
 
    // Find the leftmost node in Binary Tree 
    Node cur = leftMost(root);
 
    while (cur != null)
    {
        Console.Write(cur.key + " ");
 
        // If this Node is a thread Node, then go to 
        // inorder successor 
        if (cur.isThreaded)
        {
            cur = cur.right;
        }
 
        else // Else go to the leftmost child in right subtree
        {
            cur = leftMost(cur.right);
        }
    }
}
 
// A utility function to create a new node 
public static Node newNode(int key)
{
    Node temp = new Node();
    temp.left = temp.right = null;
    temp.key = key;
    return temp;
}
 
// Driver program to test above functions 
public static void Main(string[] args)
{
   /*       1 
            / \ 
           2   3 
          / \ / \ 
         4  5 6  7   */
    Node root = newNode(1);
    root.left = newNode(2);
    root.right = newNode(3);
    root.left.left = newNode(4);
    root.left.right = newNode(5);
    root.right.left = newNode(6);
    root.right.right = newNode(7);
 
    createThreaded(root);
 
    Console.WriteLine("Inorder traversal of created " + "threaded tree is\n");
    inOrder(root);
}
}
 
  // This code is contributed by Shrikant13


Javascript


如何将给定的二叉树转换为线程二叉树?
我们在这里讨论了基于队列的解决方案。在这篇文章中,讨论了不需要队列的节省空间的解决方案。
这个想法是基于我们从有序前驱链接到节点的事实。我们链接那些位于节点子树中的有序前驱。因此,如果节点的左边不为 NULL,我们会找到节点的有序前驱。一个节点的有序前驱(其左边为NULL)是左孩子中最右边的节点。一旦我们找到前任,我们将一个线程从它链接到当前节点。
以下是上述思想的实现。

C++

/* C++ program to convert a Binary Tree to
    Threaded Tree */
#include 
using namespace std;
 
/* Structure of a node in threaded binary tree */
struct Node
{
    int key;
    Node *left, *right;
 
    // Used to indicate whether the right pointer
    // is a normal right pointer or a pointer
    // to inorder successor.
    bool isThreaded;
};
 
// Converts tree with given root to threaded
// binary tree.
// This function returns rightmost child of
// root.
Node *createThreaded(Node *root)
{
    // Base cases : Tree is empty or has single
    //              node
    if (root == NULL)
        return NULL;
    if (root->left == NULL &&
        root->right == NULL)
        return root;
 
    // Find predecessor if it exists
    if (root->left != NULL)
    {
        // Find predecessor of root (Rightmost
        // child in left subtree)
        Node* l = createThreaded(root->left);
 
        // Link a thread from predecessor to
        // root.
        l->right = root;
        l->isThreaded = true;
    }
 
    // If current node is rightmost child
    if (root->right == NULL)
        return root;
 
    // Recur for right subtree.
    return createThreaded(root->right);
}
 
// A utility function to find leftmost node
// in a binary tree rooted with 'root'.
// This function is used in inOrder()
Node *leftMost(Node *root)
{
    while (root != NULL && root->left != NULL)
        root = root->left;
    return root;
}
 
// Function to do inorder traversal of a threadded
// binary tree
void inOrder(Node *root)
{
    if (root == NULL) return;
 
    // Find the leftmost node in Binary Tree
    Node *cur = leftMost(root);
 
    while (cur != NULL)
    {
        cout << cur->key << " ";
 
        // If this Node is a thread Node, then go to
        // inorder successor
        if (cur->isThreaded)
            cur = cur->right;
 
        else // Else go to the leftmost child in right subtree
            cur = leftMost(cur->right);
    }
}
 
// A utility function to create a new node
Node *newNode(int key)
{
    Node *temp = new Node;
    temp->left = temp->right = NULL;
    temp->key = key;
    return temp;
}
 
// Driver program to test above functions
int main()
{
    /*       1
            / \
           2   3
          / \ / \
         4  5 6  7   */
    Node *root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    root->right->left = newNode(6);
    root->right->right = newNode(7);
 
    createThreaded(root);
 
    cout << "Inorder traversal of created "
            "threaded tree is\n";
    inOrder(root);
    return 0;
}

Java

/* Java program to convert a Binary Tree to
    Threaded Tree */
import java.util.*;
class solution
{
  
   
/* structure of a node in threaded binary tree */
static class Node
{
    int key;
    Node left, right;
   
    // Used to indicate whether the right pointer
    // is a normal right pointer or a pointer
    // to inorder successor.
    boolean isThreaded;
};
   
// Converts tree with given root to threaded
// binary tree.
// This function returns rightmost child of
// root.
static Node createThreaded(Node root)
{
    // Base cases : Tree is empty or has single
    //              node
    if (root == null)
        return null;
    if (root.left == null &&
        root.right == null)
        return root;
   
    // Find predecessor if it exists
    if (root.left != null)
    {
        // Find predecessor of root (Rightmost
        // child in left subtree)
        Node l = createThreaded(root.left);
   
        // Link a thread from predecessor to
        // root.
        l.right = root;
        l.isThreaded = true;
    }
   
    // If current node is rightmost child
    if (root.right == null)
        return root;
   
    // Recur for right subtree.
    return createThreaded(root.right);
}
   
// A utility function to find leftmost node
// in a binary tree rooted with 'root'.
// This function is used in inOrder()
static Node leftMost(Node root)
{
    while (root != null && root.left != null)
        root = root.left;
    return root;
}
   
// Function to do inorder traversal of a threadded
// binary tree
static void inOrder(Node root)
{
    if (root == null) return;
   
    // Find the leftmost node in Binary Tree
    Node cur = leftMost(root);
   
    while (cur != null)
    {
        System.out.print(cur.key + " ");
   
        // If this Node is a thread Node, then go to
        // inorder successor
        if (cur.isThreaded)
            cur = cur.right;
   
        else // Else go to the leftmost child in right subtree
            cur = leftMost(cur.right);
    }
}
   
// A utility function to create a new node
static Node newNode(int key)
{
    Node temp = new Node();
    temp.left = temp.right = null;
    temp.key = key;
    return temp;
}
   
// Driver program to test above functions
public static void main(String args[])
{
   /*       1
            / \
           2   3
          / \ / \
         4  5 6  7   */
    Node root = newNode(1);
    root.left = newNode(2);
    root.right = newNode(3);
    root.left.left = newNode(4);
    root.left.right = newNode(5);
    root.right.left = newNode(6);
    root.right.right = newNode(7);
   
    createThreaded(root);
   
    System.out.println("Inorder traversal of created "+"threaded tree is\n");
    inOrder(root); 
}
}
//contributed by Arnab Kundu

Python3

# Python3 program to convert a Binary Tree to
# Threaded Tree
 
# A utility function to create a new node
class newNode:
    def __init__(self, key):
        self.left = self.right = None
        self.key = key
        self.isThreaded = None
         
# Converts tree with given root to threaded
# binary tree.
# This function returns rightmost child of
# root.
def createThreaded(root):
     
    # Base cases : Tree is empty or has 
    #               single node
    if root == None:
        return None
    if root.left == None and root.right == None:
        return root
 
    # Find predecessor if it exists
    if root.left != None:
         
        # Find predecessor of root (Rightmost
        # child in left subtree)
        l = createThreaded(root.left)
 
        # Link a thread from predecessor
        # to root.
        l.right = root
        l.isThreaded = True
 
    # If current node is rightmost child
    if root.right == None:
        return root
 
    # Recur for right subtree.
    return createThreaded(root.right)
 
# A utility function to find leftmost node
# in a binary tree rooted with 'root'.
# This function is used in inOrder()
def leftMost(root):
    while root != None and root.left != None:
        root = root.left
    return root
 
# Function to do inorder traversal of a
# threaded binary tree
def inOrder(root):
    if root == None:
        return
 
    # Find the leftmost node in Binary Tree
    cur = leftMost(root)
 
    while cur != None:
        print(cur.key, end = " ")
 
        # If this Node is a thread Node, then
        # go to inorder successor
        if cur.isThreaded:
            cur = cur.right
 
        else: # Else go to the leftmost child
              # in right subtree
            cur = leftMost(cur.right)
 
# Driver Code
if __name__ == '__main__':
     
    #         1
    #     / \
    #     2 3
    #     / \ / \
    #     4 5 6 7
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
    root.left.left = newNode(4)
    root.left.right = newNode(5)
    root.right.left = newNode(6)
    root.right.right = newNode(7)
 
    createThreaded(root)
 
    print("Inorder traversal of created",
                      "threaded tree is")
    inOrder(root)
 
# This code is contributed by PranchalK

C#

using System;
 
/* C# program to convert a Binary Tree to 
    Threaded Tree */
public class solution
{
 
 
/* structure of a node in threaded binary tree */
public class Node
{
    public int key;
    public Node left, right;
 
    // Used to indicate whether the right pointer 
    // is a normal right pointer or a pointer 
    // to inorder successor. 
    public bool isThreaded;
}
 
// Converts tree with given root to threaded 
// binary tree. 
// This function returns rightmost child of 
// root. 
public static Node createThreaded(Node root)
{
    // Base cases : Tree is empty or has single 
    //              node 
    if (root == null)
    {
        return null;
    }
    if (root.left == null && root.right == null)
    {
        return root;
    }
 
    // Find predecessor if it exists 
    if (root.left != null)
    {
        // Find predecessor of root (Rightmost 
        // child in left subtree) 
        Node l = createThreaded(root.left);
 
        // Link a thread from predecessor to 
        // root. 
        l.right = root;
        l.isThreaded = true;
    }
 
    // If current node is rightmost child 
    if (root.right == null)
    {
        return root;
    }
 
    // Recur for right subtree. 
    return createThreaded(root.right);
}
 
// A utility function to find leftmost node 
// in a binary tree rooted with 'root'. 
// This function is used in inOrder() 
public static Node leftMost(Node root)
{
    while (root != null && root.left != null)
    {
        root = root.left;
    }
    return root;
}
 
// Function to do inorder traversal of a threadded 
// binary tree 
public static void inOrder(Node root)
{
    if (root == null)
    {
        return;
    }
 
    // Find the leftmost node in Binary Tree 
    Node cur = leftMost(root);
 
    while (cur != null)
    {
        Console.Write(cur.key + " ");
 
        // If this Node is a thread Node, then go to 
        // inorder successor 
        if (cur.isThreaded)
        {
            cur = cur.right;
        }
 
        else // Else go to the leftmost child in right subtree
        {
            cur = leftMost(cur.right);
        }
    }
}
 
// A utility function to create a new node 
public static Node newNode(int key)
{
    Node temp = new Node();
    temp.left = temp.right = null;
    temp.key = key;
    return temp;
}
 
// Driver program to test above functions 
public static void Main(string[] args)
{
   /*       1 
            / \ 
           2   3 
          / \ / \ 
         4  5 6  7   */
    Node root = newNode(1);
    root.left = newNode(2);
    root.right = newNode(3);
    root.left.left = newNode(4);
    root.left.right = newNode(5);
    root.right.left = newNode(6);
    root.right.right = newNode(7);
 
    createThreaded(root);
 
    Console.WriteLine("Inorder traversal of created " + "threaded tree is\n");
    inOrder(root);
}
}
 
  // This code is contributed by Shrikant13

Javascript


输出:

Inorder traversal of created threaded tree is
4 2 5 1 6 3 7

该算法在 O(n) 时间复杂度和 O(1) 空间中工作,而不是函数调用堆栈。