📜  在双向链表中提取二叉树的叶子

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

在双向链表中提取二叉树的叶子

给定一棵二叉树,将它的所有叶子提取到一个双链接列表 (DLL) 中。请注意,DLL 需要就地创建。假设DLL和二叉树的节点结构相同,只是左右指针的含义不同。在 DLL 中,left 表示前一个指针,right 表示下一个指针。

Let the following be input binary tree
        1
     /     \
    2       3
   / \       \
  4   5       6
 / \         / \
7   8       9   10


Output:
Doubly Linked List
785910

Modified Tree:
        1
     /     \
    2       3
   /         \
  4           6 

我们需要遍历所有叶子并通过改变它们的左右指针来连接它们。我们还需要通过更改父节点中的左或右指针将它们从二叉树中删除。可以有很多方法来解决这个问题。在下面的实现中,我们在当前链表的开头添加叶子,并使用指向头指针的指针更新链表的头。由于我们在开头插入,我们需要以相反的顺序处理叶子。对于逆序,我们首先遍历右子树,然后是左子树。我们使用返回值来更新父节点中的左或右指针。

C++
// C++ program to extract leaves of
// a Binary Tree in a Doubly Linked List
#include 
using namespace std;
 
// Structure for tree and linked list
class Node
{
    public:
    int data;
    Node *left, *right;
};
 
// Main function which extracts all
// leaves from given Binary Tree.
// The function returns new root of
// Binary Tree (Note that root may change
// if Binary Tree has only one node).
// The function also sets *head_ref as
// head of doubly linked list. left pointer
// of tree is used as prev in DLL
// and right pointer is used as next
Node* extractLeafList(Node *root, Node **head_ref)
{
// Base cases
if (root == NULL) return NULL;
 
if (root->left == NULL && root->right == NULL)
{
    // This node is going to be added
    // to doubly linked list of leaves,
    // set right pointer of this node
    // as previous head of DLL. We
    // don't need to set left pointer 
    // as left is already NULL
    root->right = *head_ref;
 
    // Change left pointer of previous head
    if (*head_ref != NULL) (*head_ref)->left = root;
 
    // Change head of linked list
    *head_ref = root;
 
    return NULL; // Return new root
}
 
// Recur for right and left subtrees
root->right = extractLeafList(root->right, head_ref);
root->left = extractLeafList(root->left, head_ref);
 
return root;
}
 
// Utility function for allocating node for Binary Tree.
Node* newNode(int data)
{
    Node* node = new Node();
    node->data = data;
    node->left = node->right = NULL;
    return node;
}
 
// Utility function for printing tree in In-Order.
void print(Node *root)
{
    if (root != NULL)
    {
        print(root->left);
        cout<data<<" ";
        print(root->right);
    }
}
 
// Utility function for printing double linked list.
void printList(Node *head)
{
    while (head)
    {
        cout<data<<" ";
        head = head->right;
    }
}
 
// Driver code
int main()
{
    Node *head = NULL;
    Node *root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    root->right->right = newNode(6);
    root->left->left->left = newNode(7);
    root->left->left->right = newNode(8);
    root->right->right->left = newNode(9);
    root->right->right->right = newNode(10);
 
    cout << "Inorder Traversal of given Tree is:\n";
    print(root);
 
    root = extractLeafList(root, &head);
 
    cout << "\nExtracted Double Linked list is:\n";
    printList(head);
 
    cout << "\nInorder traversal of modified tree is:\n";
    print(root);
    return 0;
}
 
// This code is contributed by rathbhupendra


C
// C program to extract leaves of a Binary Tree in a Doubly Linked List
#include 
#include 
 
// Structure for tree and linked list
struct Node
{
    int data;
    struct Node *left, *right;
};
 
// Main function which extracts all leaves from given Binary Tree.
// The function returns new root of Binary Tree (Note that root may change
// if Binary Tree has only one node).  The function also sets *head_ref as
// head of doubly linked list.  left pointer of tree is used as prev in DLL
// and right pointer is used as next
struct Node* extractLeafList(struct Node *root, struct Node **head_ref)
{
   // Base cases
   if (root == NULL)  return NULL;
 
   if (root->left == NULL && root->right == NULL)
   {
       // This node is going to be added to doubly linked list
       // of leaves, set right pointer of this node as previous
       // head of DLL. We don't need to set left pointer as left
       // is already NULL
       root->right = *head_ref;
 
       // Change left pointer of previous head
       if (*head_ref != NULL) (*head_ref)->left = root;
 
       // Change head of linked list
       *head_ref = root;
 
       return NULL;  // Return new root
   }
 
   // Recur for right and left subtrees
   root->right = extractLeafList(root->right, head_ref);
   root->left  = extractLeafList(root->left, head_ref);
 
   return root;
}
 
// Utility function for allocating node for Binary Tree.
struct Node* newNode(int data)
{
    struct Node* node = (struct Node*)malloc(sizeof(struct Node));
    node->data = data;
    node->left = node->right = NULL;
    return node;
}
 
// Utility function for printing tree in In-Order.
void print(struct Node *root)
{
    if (root != NULL)
    {
         print(root->left);
         printf("%d ",root->data);
         print(root->right);
    }
}
 
// Utility function for printing double linked list.
void printList(struct Node *head)
{
     while (head)
     {
         printf("%d ", head->data);
         head = head->right;
     }
}
 
// Driver program to test above function
int main()
{
     struct Node *head = NULL;
     struct Node *root = newNode(1);
     root->left = newNode(2);
     root->right = newNode(3);
     root->left->left = newNode(4);
     root->left->right = newNode(5);
     root->right->right = newNode(6);
     root->left->left->left = newNode(7);
     root->left->left->right = newNode(8);
     root->right->right->left = newNode(9);
     root->right->right->right = newNode(10);
 
     printf("Inorder Traversal of given Tree is:\n");
     print(root);
 
     root = extractLeafList(root, &head);
 
     printf("\nExtracted Double Linked list is:\n");
     printList(head);
 
     printf("\nInorder traversal of modified tree is:\n");
     print(root);
     return 0;
}


Java
// Java program to extract leaf nodes from binary tree
// using double linked list
  
// A binary tree node
class Node
{
    int data;
    Node left, right;
  
    Node(int item)
    {
        data = item;
        right = left = null;
    }
}
  
public class BinaryTree
{
    Node root;
    Node head; // will point to head of DLL 
    Node prev; // temporary pointer
  
    // The main function that links the list list to be traversed
    public Node extractLeafList(Node root)
    {
        if (root == null)
            return null;
        if (root.left == null && root.right == null)
        {
            if (head == null)
            {
                head = root;
                prev = root;
            }
            else
            {
                prev.right = root;
                root.left = prev;
                prev = root;
            }
            return null;
        }
        root.left = extractLeafList(root.left);
        root.right = extractLeafList(root.right);
        return root;
    }
  
    //Prints the DLL in both forward and reverse directions.
    public void printDLL(Node head)
    {
        Node last = null;
        while (head != null)
        {
            System.out.print(head.data + " ");
            last = head;
            head = head.right;
        }
    }
  
    void inorder(Node node)
    {
        if (node == null)
            return;
        inorder(node.left);
        System.out.print(node.data + " ");
        inorder(node.right);
    }
  
    // Driver program to test above functions
    public static void main(String args[])
    {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(1);
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);
  
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(5);
        tree.root.right.right = new Node(6);
        tree.root.left.left.left = new Node(7);
        tree.root.left.left.right = new Node(8);
        tree.root.right.right.left = new Node(9);
        tree.root.right.right.right = new Node(10);
  
        System.out.println("Inorder traversal of given tree is : ");
        tree.inorder(tree.root);
        tree.extractLeafList(tree.root);
        System.out.println("");
        System.out.println("Extracted double link list is : ");
        tree.printDLL(tree.head);
        System.out.println("");
        System.out.println("Inorder traversal of modified tree is : ");
        tree.inorder(tree.root);
    }
}
 
// This code has been contributed by Mayank Jaiswal(mayank_24)


Python3
# Python program to extract leaf nodes from binary tree
# using double linked list
 
# A binary tree node
class Node:
     
    # Constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# Main function which extracts all leaves from given Binary Tree.
# The function returns new root of Binary Tree (Note that
# root may change if Binary Tree has only one node).
# The function also sets *head_ref as head of doubly linked list.
# left pointer of tree is used as prev in DLL
# and right pointer is used as next
def extractLeafList(root):
     
    # Base Case
    if root is None:
        return None
 
    if root.left is None and root.right is None:
        # This node is going to be added to doubly linked
        # list of leaves, set pointer of this node as
        # previous head of DLL. We don't need to set left
        # pointer as left is already None
        root.right = extractLeafList.head
         
        # Change the left pointer of previous head
        if extractLeafList.head is not None:
            extractLeafList.head.left = root
 
        # Change head of linked list
        extractLeafList.head = root
         
        return None # Return new root
 
    # Recur for right and left subtrees
    root.right = extractLeafList(root.right)
    root.left = extractLeafList(root.left)
     
    return root
 
# Utility function for printing tree in InOrder
def printInorder(root):
    if root is not None:
        printInorder(root.left)
        print (root.data,end=" ")
        printInorder(root.right)
 
 
def printList(head):
    while(head):
        if head.data is not None:
            print (head.data,end=" ")
        head = head.right
 
# Driver program to test above function
extractLeafList.head = Node(None)
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.right = Node(6)
root.left.left.left = Node(7)
root.left.left.right = Node(8)
root.right.right.left = Node(9)
root.right.right.right = Node(10)
 
print ("Inorder traversal of given tree is:")
printInorder(root)
 
root = extractLeafList(root)
 
print ("\nExtract Double Linked List is:")
printList(extractLeafList.head)
 
print ("\nInorder traversal of modified tree is:")
printInorder(root)


C#
// C# program to extract leaf
// nodes from binary tree
// using double linked list
using System;
 
// A binary tree node
public class Node
{
    public int data;
    public Node left, right;
 
    public Node(int item)
    {
        data = item;
        right = left = null;
    }
}
 
public class BinaryTree
{
    Node root;
    Node head; // will point to head of DLL
    Node prev; // temporary pointer
 
    // The main function that links
    // the list list to be traversed
    public Node extractLeafList(Node root)
    {
        if (root == null)
            return null;
        if (root.left == null && root.right == null)
        {
            if (head == null)
            {
                head = root;
                prev = root;
            }
            else
            {
                prev.right = root;
                root.left = prev;
                prev = root;
            }
            return null;
        }
        root.left = extractLeafList(root.left);
        root.right = extractLeafList(root.right);
        return root;
    }
 
    // Prints the DLL in both forward
    // and reverse directions.
    public void printDLL(Node head)
    {
        Node last = null;
        while (head != null)
        {
            Console.Write(head.data + " ");
            last = head;
            head = head.right;
        }
    }
 
    void inorder(Node node)
    {
        if (node == null)
            return;
        inorder(node.left);
        Console.Write(node.data + " ");
        inorder(node.right);
    }
 
    // Driver code
    public static void Main(String []args)
    {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(1);
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);
 
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(5);
        tree.root.right.right = new Node(6);
        tree.root.left.left.left = new Node(7);
        tree.root.left.left.right = new Node(8);
        tree.root.right.right.left = new Node(9);
        tree.root.right.right.right = new Node(10);
 
        Console.WriteLine("Inorder traversal of given tree is : ");
        tree.inorder(tree.root);
        tree.extractLeafList(tree.root);
        Console.WriteLine("");
        Console.WriteLine("Extracted double link list is : ");
        tree.printDLL(tree.head);
        Console.WriteLine("");
        Console.WriteLine("Inorder traversal of modified tree is : ");
        tree.inorder(tree.root);
    }
}
 
// This code has been contributed by 29AjayKumar


Javascript


输出
Inorder Traversal of given Tree is:
7 4 8 2 5 1 3 9 6 10 
Extracted Double Linked list is:
7 8 5 9 10 
Inorder traversal of modified tree is:
4 2 1 3 6 

时间复杂度: O(n),解决方案对给定的二叉树进行一次遍历。