📜  将给定的二叉树转换为双向链表 |设置 2

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

将给定的二叉树转换为双向链表 |设置 2

给定二叉树 (BT),将其转换为双向链表 (DLL)。节点中的左指针和右指针分别用作转换后的DLL中的前一个指针和下一个指针。对于给定的二叉树,DLL 中的节点顺序必须与 Inorder 中的相同。 Inorder遍历的第一个节点(BT中最左边的节点)必须是DLL的头节点。

树到列表

这篇文章已经讨论了这个问题的解决方案。
在这篇文章中,讨论了另一种简单有效的解决方案。这里讨论的解决方案有两个简单的步骤。
1)修复左指针在这一步中,我们将左指针更改为指向 DLL 中的先前节点。这个想法很简单,我们按顺序遍历树。为了遍历,我们跟踪先前访问过的节点并将左指针更改为前一个节点。请参阅下面的fixPrevPtr()实现。
2)修复右指针以上内容直观且简单。如何更改右指针以指向 DLL 中的下一个节点?这个想法是使用在步骤 1 中固定的左指针。我们从二叉树 (BT) 中最右边的节点开始。最右边的节点是 DLL 中的最后一个节点。由于左指针被更改为指向 DLL 中的前一个节点,我们可以使用这些指针线性遍历整个 DLL。遍历将从最后一个节点到第一个节点。在遍历 DLL 时,我们跟踪先前访问过的节点并将右指针更改为前一个节点。请参阅下面的fixNextPtr()实现。

C++
// A simple inorder traversal based
// program to convert a Binary Tree to DLL
#include 
using namespace std;
 
// A tree node
class node
{
    public:
    int data;
    node *left, *right;
};
 
// A utility function to create
// a new tree node
node *newNode(int data)
{
    node *Node = new node();
    Node->data = data;
    Node->left = Node->right = NULL;
    return(Node);
}
 
// Standard Inorder traversal of tree
void inorder(node *root)
{
    if (root != NULL)
    {
        inorder(root->left);
        cout << "\t" << root->data;
        inorder(root->right);
    }
}
 
// Changes left pointers to work as
// previous pointers in converted DLL
// The function simply does inorder
// traversal of Binary Tree and updates
// left pointer using previously visited node
void fixPrevPtr(node *root)
{
    static node *pre = NULL;
 
    if (root != NULL)
    {
        fixPrevPtr(root->left);
        root->left = pre;
        pre = root;
        fixPrevPtr(root->right);
    }
}
 
// Changes right pointers to work
// as next pointers in converted DLL
node *fixNextPtr(node *root)
{
    node *prev = NULL;
 
    // Find the right most node
    // in BT or last node in DLL
    while (root && root->right != NULL)
        root = root->right;
 
    // Start from the rightmost node,
    // traverse back using left pointers.
    // While traversing, change right pointer of nodes.
    while (root && root->left != NULL)
    {
        prev = root;
        root = root->left;
        root->right = prev;
    }
 
    // The leftmost node is head
    // of linked list, return it
    return (root);
}
 
// The main function that converts
// BST to DLL and returns head of DLL
node *BTToDLL(node *root)
{
    // Set the previous pointer
    fixPrevPtr(root);
 
    // Set the next pointer and return head of DLL
    return fixNextPtr(root);
}
 
// Traverses the DLL from left to right
void printList(node *root)
{
    while (root != NULL)
    {
        cout<<"\t"<data;
        root = root->right;
    }
}
 
// Driver code
int main(void)
{
    // Let us create the tree
    // shown in above diagram
    node *root = newNode(10);
    root->left = newNode(12);
    root->right = newNode(15);
    root->left->left = newNode(25);
    root->left->right = newNode(30);
    root->right->left = newNode(36);
 
    cout<<"\n\t\tInorder Tree Traversal\n\n";
    inorder(root);
 
    node *head = BTToDLL(root);
 
    cout << "\n\n\t\tDLL Traversal\n\n";
    printList(head);
    return 0;
}
 
// This code is contributed by rathbhupendra


C
// A simple inorder traversal based program to convert a Binary Tree to DLL
#include
#include
 
// A tree node
struct node
{
    int data;
    struct node *left, *right;
};
 
// A utility function to create a new tree node
struct node *newNode(int data)
{
    struct node *node = (struct node *)malloc(sizeof(struct node));
    node->data = data;
    node->left = node->right = NULL;
    return(node);
}
 
// Standard Inorder traversal of tree
void inorder(struct node *root)
{
    if (root != NULL)
    {
        inorder(root->left);
        printf("\t%d",root->data);
        inorder(root->right);
    }
}
 
// Changes left pointers to work as previous pointers in converted DLL
// The function simply does inorder traversal of Binary Tree and updates
// left pointer using previously visited node
void fixPrevPtr(struct node *root)
{
    static struct node *pre = NULL;
 
    if (root != NULL)
    {
        fixPrevPtr(root->left);
        root->left = pre;
        pre = root;
        fixPrevPtr(root->right);
    }
}
 
// Changes right pointers to work as next pointers in converted DLL
struct node *fixNextPtr(struct node *root)
{
    struct node *prev = NULL;
 
    // Find the right most node in BT or last node in DLL
    while (root && root->right != NULL)
        root = root->right;
 
    // Start from the rightmost node, traverse back using left pointers.
    // While traversing, change right pointer of nodes.
    while (root && root->left != NULL)
    {
        prev = root;
        root = root->left;
        root->right = prev;
    }
 
    // The leftmost node is head of linked list, return it
    return (root);
}
 
// The main function that converts BST to DLL and returns head of DLL
struct node *BTToDLL(struct node *root)
{
    // Set the previous pointer
    fixPrevPtr(root);
 
    // Set the next pointer and return head of DLL
    return fixNextPtr(root);
}
 
// Traverses the DLL from left to right
void printList(struct node *root)
{
    while (root != NULL)
    {
        printf("\t%d", root->data);
        root = root->right;
    }
}
 
// Driver program to test above functions
int main(void)
{
    // Let us create the tree shown in above diagram
    struct node *root = newNode(10);
    root->left        = newNode(12);
    root->right       = newNode(15);
    root->left->left  = newNode(25);
    root->left->right = newNode(30);
    root->right->left = newNode(36);
 
    printf("\n\t\tInorder Tree Traversal\n\n");
    inorder(root);
 
    struct node *head = BTToDLL(root);
 
    printf("\n\n\t\tDLL Traversal\n\n");
    printList(head);
    return 0;
}


Java
// Java program to convert BTT to DLL using
// simple inorder traversal
 
public class BinaryTreeToDLL
{
    static class node
    {
        int data;
        node left, right;
 
        public node(int data)
        {
            this.data = data;
        }
    }
 
    static node prev;
 
    // Changes left pointers to work as previous
    // pointers in converted DLL The function
    // simply does inorder traversal of Binary
    // Tree and updates left pointer using
    // previously visited node
    static void fixPrevptr(node root)
    {
        if (root == null)
            return;
 
        fixPrevptr(root.left);
        root.left = prev;
        prev = root;
        fixPrevptr(root.right);
 
    }
 
    // Changes right pointers to work
    // as next pointers in converted DLL
    static node fixNextptr(node root)
    {       
        // Find the right most node in
        // BT or last node in DLL
        while (root.right != null)
            root = root.right;
 
        // Start from the rightmost node, traverse
        // back using left pointers. While traversing,
        // change right pointer of nodes
        while (root != null && root.left != null)
        {
            node left = root.left;
            left.right = root;
            root = root.left;
        }
 
        // The leftmost node is head of linked list, return it
        return root;
    }
 
    static node BTTtoDLL(node root)
    {
        prev = null;
 
        // Set the previous pointer
        fixPrevptr(root);
 
        // Set the next pointer and return head of DLL
        return fixNextptr(root);
    }
 
    // Traverses the DLL from left to right
    static void printlist(node root)
    {
        while (root != null)
        {
            System.out.print(root.data + " ");
            root = root.right;
        }
    }
 
    // Standard Inorder traversal of tree
    static void inorder(node root)
    {
        if (root == null)
            return;
        inorder(root.left);
        System.out.print(root.data + " ");
        inorder(root.right);
    }
 
    public static void main(String[] args)
    {
        // Let us create the tree shown in above diagram
        node root = new node(10);
        root.left = new node(12);
        root.right = new node(15);
        root.left.left = new node(25);
        root.left.right = new node(30);
        root.right.left = new node(36);
 
        System.out.println("Inorder Tree Traversal");
        inorder(root);
 
        node head = BTTtoDLL(root);
 
        System.out.println("\nDLL Traversal");
        printlist(head);
    }
}
 
// This code is contributed by Rishabh Mahrsee


Python3
# A simple inorder traversal based program to convert a
# Binary Tree to DLL
 
# A Binary Tree node
class Node:
     
    # Constructor to create a new tree node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# Standard Inorder traversal of tree
def inorder(root):
     
    if root is not None:
        inorder(root.left)
        print ("\t%d" %(root.data),end=" ")
        inorder(root.right)
 
# Changes left pointers to work as previous pointers
# in converted DLL
# The function simply does inorder traversal of
# Binary Tree and updates
# left pointer using previously visited node
def fixPrevPtr(root):
    if root is not None:
        fixPrevPtr(root.left)
        root.left = fixPrevPtr.pre
        fixPrevPtr.pre = root
        fixPrevPtr(root.right)
 
# Changes right pointers to work as next pointers in
# converted DLL
def fixNextPtr(root):
 
    prev = None
    # Find the right most node in BT or last node in DLL
    while(root and root.right != None):
        root = root.right
 
    # Start from the rightmost node, traverse back using
    # left pointers
    # While traversing, change right pointer of nodes
    while(root and root.left != None):
        prev = root
        root = root.left
        root.right = prev
 
    # The leftmost node is head of linked list, return it
    return root
 
# The main function that converts BST to DLL and returns
# head of DLL
def BTToDLL(root):
     
    # Set the previous pointer
    fixPrevPtr(root)
 
    # Set the next pointer and return head of DLL
    return fixNextPtr(root)
 
# Traversses the DLL from left to right
def printList(root):
    while(root != None):
        print ("\t%d" %(root.data),end=" ")
        root = root.right
 
# Driver program to test above function
root = Node(10)
root.left = Node(12)
root.right = Node(15)
root.left.left = Node(25)
root.left.right = Node(30)
root.right.left = Node(36)
 
print ("Inorder Tree Traversal")
inorder(root)
 
# Static variable pre for function fixPrevPtr
fixPrevPtr.pre = None
head = BTToDLL(root)
 
print ("\nDLL Traversal")
printList(head)
     
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)


C#
// C# program to convert BTT to DLL using
// simple inorder traversal
using System;
 
class GFG
{
public class node
{
    public int data;
    public node left, right;
 
    public node(int data)
    {
        this.data = data;
    }
}
 
public static node prev;
 
// Changes left pointers to work as previous
// pointers in converted DLL The function
// simply does inorder traversal of Binary
// Tree and updates left pointer using
// previously visited node
public static void fixPrevptr(node root)
{
    if (root == null)
    {
        return;
    }
 
    fixPrevptr(root.left);
    root.left = prev;
    prev = root;
    fixPrevptr(root.right);
 
}
 
// Changes right pointers to work
// as next pointers in converted DLL
public static node fixNextptr(node root)
{
    // Find the right most node in
    // BT or last node in DLL
    while (root.right != null)
    {
        root = root.right;
    }
 
    // Start from the rightmost node, traverse
    // back using left pointers. While traversing,
    // change right pointer of nodes
    while (root != null && root.left != null)
    {
        node left = root.left;
        left.right = root;
        root = root.left;
    }
 
    // The leftmost node is head of
    // linked list, return it
    return root;
}
 
public static node BTTtoDLL(node root)
{
    prev = null;
 
    // Set the previous pointer
    fixPrevptr(root);
 
    // Set the next pointer and
    // return head of DLL
    return fixNextptr(root);
}
 
// Traverses the DLL from left to right
public static void printlist(node root)
{
    while (root != null)
    {
        Console.Write(root.data + " ");
        root = root.right;
    }
}
 
// Standard Inorder traversal of tree
public static void inorder(node root)
{
    if (root == null)
    {
        return;
    }
    inorder(root.left);
    Console.Write(root.data + " ");
    inorder(root.right);
}
 
public static void Main()
{
    // Let us create the tree
    // shown in above diagram
    node root = new node(10);
    root.left = new node(12);
    root.right = new node(15);
    root.left.left = new node(25);
    root.left.right = new node(30);
    root.right.left = new node(36);
 
    Console.WriteLine("Inorder Tree Traversal");
    inorder(root);
 
    node head = BTTtoDLL(root);
 
    Console.WriteLine("\nDLL Traversal");
    printlist(head);
}
}
 
// This code is contributed by Shrikant13


Javascript


输出:

Inorder Tree Traversal

        25      12      30      10      36      15

                DLL Traversal

        25      12      30      10      36      15

时间复杂度: O(n),其中 n 是给定二叉树中的节点数。该解决方案只是对所有二叉树节点进行两次遍历。