📜  以螺旋方式将二叉树转换为双向链表

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

以螺旋方式将二叉树转换为双向链表

给定一棵二叉树,将其转换为双向链表,其中节点以螺旋方式表示。二叉树节点的左指针应该作为创建DLL的前一个节点,右指针应该作为下一个节点。
该解决方案不应为 DLL 节点分配额外的内存。它应该使用二叉树节点来创建 DLL,即只允许更改指针

例如,对于左侧的树,双向链表可以是,
1 2 3 7 6 5 4 8 9 10 11 13 14 或
1 3 2 4 5 6 7 14 13 11 10 9 8
我们强烈建议您最小化您的浏览器并首先自己尝试。
我们可以通过在 O(n) 时间和 O(n) 额外空间中进行螺旋顺序遍历来做到这一点。这个想法是使用可以在两端(无论是前端还是后端)扩展或收缩的 deque(双端队列)。我们做一些类似于级别顺序遍历的事情,但为了保持螺旋顺序,对于每个奇数级别,我们从前面出列节点并将其左右子节点插入到 deque 数据结构的后面。对于每个偶数级别,我们从后面出列节点并将其左右子节点插入到 deque 的前面。我们还维护一个堆栈来存储二叉树节点。每当我们从双端队列中弹出节点时,我们都会将该节点推入堆栈。稍后,我们从堆栈中弹出所有节点并推送列表开头的节点。如果我们维护一个始终指向 DLL 的最后一个节点并在最后以 O(1) 时间插入节点的尾指针,我们可以避免使用堆栈。
下面是上述想法的实现

C++
/* c++ program to convert Binary Tree into Doubly
   Linked List where the nodes are represented
   spirally. */
#include 
using namespace std;
 
// A Binary Tree Node
struct Node
{
    int data;
    struct Node *left, *right;
};
 
/* Given a reference to the head of a list and a node,
inserts the node on the front of the list. */
void push(Node** head_ref, Node* node)
{
    // Make right of given node as head and left as
    // NULL
    node->right = (*head_ref);
    node->left = NULL;
 
    // change left of head node to given node
    if ((*head_ref) !=  NULL)
        (*head_ref)->left = node ;
 
    // move the head to point to the given node
    (*head_ref) = node;
}
 
// Function to prints contents of DLL
void printList(Node *node)
{
    while (node != NULL)
    {
        cout << node->data << " ";
        node = node->right;
    }
}
 
/* Function to print corner node at each level */
void spiralLevelOrder(Node *root)
{
    // Base Case
    if (root == NULL)
        return;
 
    // Create an empty deque for doing spiral
    // level order traversal and enqueue root
    deque q;
    q.push_front(root);
 
    // create a stack to store Binary Tree nodes
    // to insert into DLL later
    stack stk;
 
    int level = 0;
    while (!q.empty())
    {
        // nodeCount indicates number of Nodes
        // at current level.
        int nodeCount = q.size();
 
        // Dequeue all Nodes of current level and
        // Enqueue all Nodes of next level
        if (level&1)    //odd level
        {
            while (nodeCount > 0)
            {
                // dequeue node from front & push it to
                // stack
                Node *node = q.front();
                q.pop_front();
                stk.push(node);
 
                // insert its left and right children
                // in the back of the deque
                if (node->left != NULL)
                    q.push_back(node->left);
                if (node->right != NULL)
                    q.push_back(node->right);
 
                nodeCount--;
            }
        }
        else      //even level
        {
            while (nodeCount > 0)
            {
                // dequeue node from the back & push it
                // to stack
                Node *node = q.back();
                q.pop_back();
                stk.push(node);
 
                // inserts its right and left children
                // in the front of the deque
                if (node->right != NULL)
                    q.push_front(node->right);
                if (node->left != NULL)
                    q.push_front(node->left);
                nodeCount--;
            }
        }
        level++;
    }
 
    // head pointer for DLL
    Node* head = NULL;
 
    // pop all nodes from stack and
    // push them in the beginning of the list
    while (!stk.empty())
    {
        push(&head, stk.top());
        stk.pop();
    }
 
    cout << "Created DLL is:\n";
    printList(head);
}
 
// Utility function to create a new tree Node
Node* newNode(int data)
{
    Node *temp = new Node;
    temp->data = data;
    temp->left = temp->right = NULL;
 
    return temp;
}
 
// Driver program to test above functions
int main()
{
    // Let us create binary tree shown in above diagram
    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);
 
    root->left->left->left  = newNode(8);
    root->left->left->right  = newNode(9);
    root->left->right->left  = newNode(10);
    root->left->right->right  = newNode(11);
    //root->right->left->left  = newNode(12);
    root->right->left->right  = newNode(13);
    root->right->right->left  = newNode(14);
    //root->right->right->right  = newNode(15);
 
    spiralLevelOrder(root);
 
    return 0;
}


Java
/* Java program to convert Binary Tree into Doubly Linked List
   where the nodes are represented spirally */
 
import java.util.*;
 
// A binary tree node
class Node
{
    int data;
    Node left, right;
 
    public Node(int data)
    {
        this.data = data;
        left = right = null;
    }
}
 
class BinaryTree
{
    Node root;
    Node head;
 
    /* Given a reference to a node,
       inserts the node on the front of the list. */
    void push(Node node)
    {
        // Make right of given node as head and left as
        // NULL
        node.right = head;
        node.left = null;
 
        // change left of head node to given node
        if (head != null)
            head.left = node;
             
        // move the head to point to the given node
        head = node;
    }
 
    // Function to prints contents of DLL
    void printList(Node node)
    {
        while (node != null)
        {
            System.out.print(node.data + " ");
            node = node.right;
        }
    }
 
    /* Function to print corner node at each level */
    void spiralLevelOrder(Node root)
    {
        // Base Case
        if (root == null)
            return;
 
        // Create an empty deque for doing spiral
        // level order traversal and enqueue root
        Deque q = new LinkedList();
        q.addFirst(root);
 
        // create a stack to store Binary Tree nodes
        // to insert into DLL later
        Stack stk = new Stack();
 
        int level = 0;
        while (!q.isEmpty())
        {
            // nodeCount indicates number of Nodes
            // at current level.
            int nodeCount = q.size();
 
            // Dequeue all Nodes of current level and
            // Enqueue all Nodes of next level
            if ((level & 1) %2 != 0) //odd level
            {
                while (nodeCount > 0)
                {
                    // dequeue node from front & push it to
                    // stack
                    Node node = q.peekFirst();
                    q.pollFirst();
                    stk.push(node);
 
                    // insert its left and right children
                    // in the back of the deque
                    if (node.left != null)
                        q.addLast(node.left);
                    if (node.right != null)
                        q.addLast(node.right);
 
                    nodeCount--;
                }
            }
            else //even level
            {
                while (nodeCount > 0)
                {
                    // dequeue node from the back & push it
                    // to stack
                    Node node = q.peekLast();
                    q.pollLast();
                    stk.push(node);
 
                    // inserts its right and left children
                    // in the front of the deque
                    if (node.right != null)
                        q.addFirst(node.right);
                    if (node.left != null)
                        q.addFirst(node.left);
                    nodeCount--;
                }
            }
            level++;
        }
 
        // pop all nodes from stack and
        // push them in the beginning of the list
        while (!stk.empty())
        {
            push(stk.peek());
            stk.pop();
        }
 
        System.out.println("Created DLL is : ");
        printList(head);
    }
 
    // Driver program to test above functions
    public static void main(String[] args)
    {
        // Let us create binary tree as shown in above diagram
        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.left = new Node(6);
        tree.root.right.right = new Node(7);
 
        tree.root.left.left.left = new Node(8);
        tree.root.left.left.right = new Node(9);
        tree.root.left.right.left = new Node(10);
        tree.root.left.right.right = new Node(11);
        // tree.root.right.left.left = new Node(12);
        tree.root.right.left.right = new Node(13);
        tree.root.right.right.left = new Node(14);
        // tree.root.right.right.right = new Node(15);
 
        tree.spiralLevelOrder(tree.root);
    }
}
 
// This code has been contributed by Mayank Jaiswal(mayank_24)


Python3
# Python3 program to convert Binary Tree
# into Doubly Linked List where the nodes
# are represented spirally.
     
# Binary tree node
class newNode:
 
    # Constructor to create a newNode
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
         
""" Given a reference to the head of a list
    and a node, inserts the node on the front
    of the list. """
def push(head_ref, node):
 
    # Make right of given node as
    # head and left as None
    node.right = (head_ref)
    node.left = None
 
    # change left of head node to
    # given node
    if ((head_ref) != None):
        (head_ref).left = node
 
    # move the head to point to
    # the given node
    (head_ref) = node
 
# Function to prints contents of DLL
def printList(node):
    i = 0
    while (i < len(node)):
     
        print(node[i].data, end = " ")
        i += 1
     
""" Function to print corner node at each level """
def spiralLevelOrder(root):
 
    # Base Case
    if (root == None):
        return
 
    # Create an empty deque for doing spiral
    # level order traversal and enqueue root
    q = []
    q.append(root)
 
    # create a stack to store Binary
    # Tree nodes to insert into DLL later
    stk = []
 
    level = 0
    while (len(q)):
     
        # nodeCount indicates number of
        # Nodes at current level.
        nodeCount = len(q)
         
        # Dequeue all Nodes of current level
        # and Enqueue all Nodes of next level
        if (level&1): # odd level
            while (nodeCount > 0):
             
                # dequeue node from front &
                # push it to stack
                node = q[0]
                q.pop(0)
                stk.append(node)
 
                # insert its left and right children
                # in the back of the deque
                if (node.left != None):
                    q.append(node.left)
                if (node.right != None):
                    q.append(node.right)
 
                nodeCount -= 1
             
        else:     # even level
         
            while (nodeCount > 0):
             
                # dequeue node from the back &
                # push it to stack
                node = q[-1]
                q.pop(-1)
                stk.append(node)
 
                # inserts its right and left
                # children in the front of
                # the deque
                if (node.right != None):
                    q.insert(0, node.right)
                if (node.left != None):
                    q.insert(0, node.left)
                nodeCount -= 1
        level += 1
         
    # head pointer for DLL
    head = []
     
    # pop all nodes from stack and push
    # them in the beginning of the list
    while (len(stk)):
     
        head.append(stk[0])
        stk.pop(0)
 
    print("Created DLL is:")
    printList(head)
 
# Driver Code
if __name__ == '__main__':
     
    """Let us create Binary Tree as
    shown in above example """
 
    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)
 
    root.left.left.left = newNode(8)
    root.left.left.right = newNode(9)
    root.left.right.left = newNode(10)
    root.left.right.right = newNode(11)
    #root.right.left.left = newNode(12)
    root.right.left.right = newNode(13)
    root.right.right.left = newNode(14)
    #root.right.right.right = newNode(15)
 
    spiralLevelOrder(root)
 
# This code is contributed
# by SHUBHAMSINGH10


C#
/* C# program to convert Binary Tree into Doubly Linked List
where the nodes are represented spirally */
using System;
using System.Collections.Generic;
 
// A binary tree node
public class Node
{
    public int data;
    public Node left, right;
 
    public Node(int data)
    {
        this.data = data;
        left = right = null;
    }
}
 
public class BinaryTree
{
    Node root;
    Node head;
 
    /* Given a reference to a node,
    inserts the node on the front of the list. */
    void push(Node node)
    {
        // Make right of given node as head and left as
        // NULL
        node.right = head;
        node.left = null;
 
        // change left of head node to given node
        if (head != null)
            head.left = node;
             
        // move the head to point to the given node
        head = node;
    }
 
    // Function to prints contents of DLL
    void printList(Node node)
    {
        while (node != null)
        {
            Console.Write(node.data + " ");
            node = node.right;
        }
    }
 
    /* Function to print corner node at each level */
    void spiralLevelOrder(Node root)
    {
        // Base Case
        if (root == null)
            return;
 
        // Create an empty deque for doing spiral
        // level order traversal and enqueue root
        LinkedList q = new LinkedList();
        q.AddFirst(root);
 
        // create a stack to store Binary Tree nodes
        // to insert into DLL later
        Stack stk = new Stack();
 
        int level = 0;
        while (q.Count != 0)
        {
            // nodeCount indicates number of Nodes
            // at current level.
            int nodeCount = q.Count;
 
            // Dequeue all Nodes of current level and
            // Enqueue all Nodes of next level
            if ((level & 1) % 2 != 0) //odd level
            {
                while (nodeCount > 0)
                {
                    // dequeue node from front & push it to
                    // stack
                    Node node = q.First.Value;
                    q.RemoveFirst();
                    stk.Push(node);
 
                    // insert its left and right children
                    // in the back of the deque
                    if (node.left != null)
                        q.AddLast(node.left);
                    if (node.right != null)
                        q.AddLast(node.right);
 
                    nodeCount--;
                }
            }
            else //even level
            {
                while (nodeCount > 0)
                {
                    // dequeue node from the back & push it
                    // to stack
                    Node node = q.Last.Value;
                    q.RemoveLast();
                    stk.Push(node);
 
                    // inserts its right and left children
                    // in the front of the deque
                    if (node.right != null)
                        q.AddFirst(node.right);
                    if (node.left != null)
                        q.AddFirst(node.left);
                    nodeCount--;
                }
            }
            level++;
        }
 
        // pop all nodes from stack and
        // push them in the beginning of the list
        while (stk.Count != 0)
        {
            push(stk.Peek());
            stk.Pop();
        }
 
        Console.WriteLine("Created DLL is : ");
        printList(head);
    }
 
    // Driver program to test above functions
    public static void Main(String[] args)
    {
        // Let us create binary tree as shown in above diagram
        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.left = new Node(6);
        tree.root.right.right = new Node(7);
 
        tree.root.left.left.left = new Node(8);
        tree.root.left.left.right = new Node(9);
        tree.root.left.right.left = new Node(10);
        tree.root.left.right.right = new Node(11);
        // tree.root.right.left.left = new Node(12);
        tree.root.right.left.right = new Node(13);
        tree.root.right.right.left = new Node(14);
        // tree.root.right.right.right = new Node(15);
 
        tree.spiralLevelOrder(tree.root);
    }
}
 
/* This code contributed by PrinciRaj1992 */


Javascript


输出 :

Created DLL is:
1 2 3 7 6 5 4 8 9 10 11 13 14