📜  将二叉树转换为循环双向链表

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

将二叉树转换为循环双向链表

给定二叉树,将其转换为循环双向链表(就地)。

  • 节点中的左指针和右指针分别用作转换后的循环链表中的前一个指针和下一个指针。
  • List 中节点的顺序必须与给定二叉树的 Inorder 相同。
  • 中序遍历的第一个节点必须是循环链表的头节点。

例子:

要列出的树

可以使用以下步骤来描述这个想法。
1)编写一个通用函数,连接两个给定的循环双重列表(这个函数在下面解释)。
2) 现在遍历给定的树
....a) 递归地将左子树转换为循环 DLL。让转换后的列表为leftList。
....a) 递归地将右子树转换为循环 DLL。让转换后的列表为rightList。
....c)制作树根的循环链表,使根的左右指向自身。
....d) 将 leftList 与单个根节点的列表连接起来。
....e) 将上述步骤 (d) 中生成的列表与 rightList 连接。
请注意,上面的代码以 Postorder 方式遍历树。我们也可以以一种有序的方式遍历。我们可以首先连接左子树和根,然后递归右子树并将结果与左根连接连接。

如何连接两个循环 DLL?

  • 获取左侧列表的最后一个节点。检索最后一个节点是一个 O(1) 操作,因为 head 的 prev 指针指向列表的最后一个节点。
  • 将其与右列表的第一个节点连接
  • 获取第二个列表的最后一个节点
  • 将它与列表的头部连接起来。

以下是上述想法的实现。

C++
// C++ Program to convert a Binary Tree
// to a Circular Doubly Linked List
#include
using namespace std;
  
// To represents a node of a Binary Tree
struct Node
{
    struct Node *left, *right;
    int data;
};
  
// A function that appends rightList at the end
// of leftList.
Node *concatenate(Node *leftList, Node *rightList)
{
    // If either of the list is empty
    // then return the other list
    if (leftList == NULL)
        return rightList;
    if (rightList == NULL)
        return leftList;
  
    // Store the last Node of left List
    Node *leftLast = leftList->left;
  
    // Store the last Node of right List
    Node *rightLast = rightList->left;
  
    // Connect the last node of Left List
    // with the first Node of the right List
    leftLast->right = rightList;
    rightList->left = leftLast;
  
    // Left of first node points to
    // the last node in the list
    leftList->left = rightLast;
  
    // Right of last node refers to the first
    // node of the List
    rightLast->right = leftList;
  
    return leftList;
}
  
// Function converts a tree to a circular Linked List
// and then returns the head of the Linked List
Node *bTreeToCList(Node *root)
{
    if (root == NULL)
        return NULL;
  
    // Recursively convert left and right subtrees
    Node *left = bTreeToCList(root->left);
    Node *right = bTreeToCList(root->right);
  
    // Make a circular linked list of single node
    // (or root). To do so, make the right and
    // left pointers of this node point to itself
    root->left = root->right = root;
  
    // Step 1 (concatenate the left list with the list 
    //         with single node, i.e., current node)
    // Step 2 (concatenate the returned list with the
    //         right List)
    return concatenate(concatenate(left, root), right);
}
  
// Display Circular Link List
void displayCList(Node *head)
{
    cout << "Circular Linked List is :\n";
    Node *itr = head;
    do
    {
        cout << itr->data <<" ";
        itr = itr->right;
    } while (head!=itr);
    cout << "\n";
}
  
  
// Create a new Node and return its address
Node *newNode(int data)
{
    Node *temp = new Node();
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
  
// Driver Program to test above function
int main()
{
    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);
  
    Node *head = bTreeToCList(root);
    displayCList(head);
  
    return 0;
}


Java
// Java Program to convert a Binary Tree to a
// Circular Doubly Linked List
  
// Node class represents a Node of a Tree
class Node
{
    int val;
    Node left,right;
  
    public Node(int val)
    {
        this.val = val;
        left = right = null;
    }
}
  
// A class to represent a tree
class Tree
{
    Node root;
    public Tree()
    {
        root = null;
    }
  
    // concatenate both the lists and returns the head
    // of the List
    public Node concatenate(Node leftList,Node rightList)
    {
        // If either of the list is empty, then
        // return the other list
        if (leftList == null)
            return rightList;
        if (rightList == null)
            return leftList;
  
        // Store the last Node of left List
        Node leftLast = leftList.left;
  
        // Store the last Node of right List
        Node rightLast = rightList.left;
  
        // Connect the last node of Left List
        // with the first Node of the right List
        leftLast.right = rightList;
        rightList.left = leftLast;
  
        // left of first node refers to
        // the last node in the list
        leftList.left = rightLast;
  
        // Right of last node refers to the first
        // node of the List
        rightLast.right = leftList;
  
        // Return the Head of the List
        return leftList;
    }
  
    // Method converts a tree to a circular
    // Link List and then returns the head
    // of the Link List
    public Node bTreeToCList(Node root)
    {
        if (root == null)
            return null;
  
        // Recursively convert left and right subtrees
        Node left = bTreeToCList(root.left);
        Node right = bTreeToCList(root.right);
  
        // Make a circular linked list of single node
        // (or root). To do so, make the right and
        // left pointers of this node point to itself
        root.left = root.right = root;
  
        // Step 1 (concatenate the left list with the list 
        //         with single node, i.e., current node)
        // Step 2 (concatenate the returned list with the
        //         right List)
        return concatenate(concatenate(left, root), right);
    }
  
    // Display Circular Link List
    public void display(Node head)
    {
        System.out.println("Circular Linked List is :");
        Node itr = head;
        do
        {
            System.out.print(itr.val+ " " );
            itr = itr.right;
        }
        while (itr != head);
        System.out.println();
    }
}
  
// Driver Code
class Main
{
    public static void main(String args[])
    {
        // Build the tree
        Tree tree = new Tree();
        tree.root = new Node(10);
        tree.root.left = new Node(12);
        tree.root.right = new Node(15);
        tree.root.left.left = new Node(25);
        tree.root.left.right = new Node(30);
        tree.root.right.left = new Node(36);
  
        // head refers to the head of the Link List
        Node head = tree.bTreeToCList(tree.root);
  
        // Display the Circular LinkedList
        tree.display(head);
    }
}


Python3
# Python3 Program to convert a Binary 
# Tree to a Circular Doubly Linked List 
  
class newNode:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
          
# A function that appends rightList 
# at the end of leftList. 
def concatenate(leftList, rightList):
      
    # If either of the list is empty 
    # then return the other list 
    if (leftList == None):
        return rightList 
    if (rightList == None): 
        return leftList 
  
    # Store the last Node of left List 
    leftLast = leftList.left 
  
    # Store the last Node of right List 
    rightLast = rightList.left 
  
    # Connect the last node of Left List 
    # with the first Node of the right List 
    leftLast.right = rightList 
    rightList.left = leftLast 
  
    # Left of first node points to 
    # the last node in the list 
    leftList.left = rightLast 
  
    # Right of last node refers to 
    # the first node of the List 
    rightLast.right = leftList 
  
    return leftList
  
# Function converts a tree to a circular 
# Linked List and then returns the head 
# of the Linked List 
def bTreeToCList(root):
    if (root == None): 
        return None
  
    # Recursively convert left and 
    # right subtrees 
    left = bTreeToCList(root.left) 
    right = bTreeToCList(root.right) 
  
    # Make a circular linked list of single 
    # node (or root). To do so, make the 
    # right and left pointers of this node
    # point to itself 
    root.left = root.right = root 
  
    # Step 1 (concatenate the left list 
    #          with the list with single 
    #         node, i.e., current node) 
    # Step 2 (concatenate the returned list
    #          with the right List) 
    return concatenate(concatenate(left, 
                            root), right)
  
# Display Circular Link List 
def displayCList(head):
    print("Circular Linked List is :") 
    itr = head
    first = 1
    while (head != itr or first):
        print(itr.data, end = " ") 
        itr = itr.right
        first = 0
    print()
  
# Driver Code
if __name__ == '__main__':
    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) 
  
    head = bTreeToCList(root) 
    displayCList(head) 
      
# This code is contributed by PranchalK


C#
// C# Program to convert a Binary Tree 
// to a Circular Doubly Linked List 
using System;
  
// Node class represents a Node of a Tree 
public class Node
{
    public int val;
    public Node left, right;
  
    public Node(int val)
    {
        this.val = val;
        left = right = null;
    }
}
  
// A class to represent a tree 
public class Tree
{
    internal Node root;
    public Tree()
    {
        root = null;
    }
  
    // concatenate both the lists 
    // and returns the head of the List 
    public virtual Node concatenate(Node leftList, 
                                    Node rightList)
    {
        // If either of the list is empty, 
        // then return the other list 
        if (leftList == null)
        {
            return rightList;
        }
        if (rightList == null)
        {
            return leftList;
        }
  
        // Store the last Node of left List 
        Node leftLast = leftList.left;
  
        // Store the last Node of right List 
        Node rightLast = rightList.left;
  
        // Connect the last node of Left List 
        // with the first Node of the right List 
        leftLast.right = rightList;
        rightList.left = leftLast;
  
        // left of first node refers to 
        // the last node in the list 
        leftList.left = rightLast;
  
        // Right of last node refers to 
        // the first node of the List 
        rightLast.right = leftList;
  
        // Return the Head of the List 
        return leftList;
    }
  
    // Method converts a tree to a circular 
    // Link List and then returns the head 
    // of the Link List 
    public virtual Node bTreeToCList(Node root)
    {
        if (root == null)
        {
            return null;
        }
  
        // Recursively convert left 
        // and right subtrees 
        Node left = bTreeToCList(root.left);
        Node right = bTreeToCList(root.right);
  
        // Make a circular linked list of single 
        // node (or root). To do so, make the 
        // right and left pointers of this node 
        // point to itself 
        root.left = root.right = root;
  
        // Step 1 (concatenate the left list with
        //          the list with single node,
        //        i.e., current node) 
        // Step 2 (concatenate the returned list 
        //           with the right List) 
        return concatenate(concatenate(left, root), right);
    }
  
    // Display Circular Link List 
    public virtual void display(Node head)
    {
        Console.WriteLine("Circular Linked List is :");
        Node itr = head;
        do
        {
            Console.Write(itr.val + " ");
            itr = itr.right;
        } while (itr != head);
        Console.WriteLine();
    }
}
  
// Driver Code 
public class GFG
{
    public static void Main(string[] args)
    {
        // Build the tree 
        Tree tree = new Tree();
        tree.root = new Node(10);
        tree.root.left = new Node(12);
        tree.root.right = new Node(15);
        tree.root.left.left = new Node(25);
        tree.root.left.right = new Node(30);
        tree.root.right.left = new Node(36);
  
        // head refers to the head of the Link List 
        Node head = tree.bTreeToCList(tree.root);
  
        // Display the Circular LinkedList 
        tree.display(head);
    }
}
  
// This code is contributed by Shrikant13


Javascript


输出:

Circular Linked List is :
25 12 30 10 36 15