将给定的二叉树转换为双向链表 |设置 3
给定一个二叉树 (BT),将其就地转换为双向链表 (DLL)。节点中的左指针和右指针分别用作转换后的DLL中的前一个指针和下一个指针。对于给定的二叉树,DLL 中的节点顺序必须与 Inorder 中的相同。 Inorder遍历的第一个节点(BT中最左边的节点)必须是DLL的头节点。
针对这个问题讨论了以下两种不同的解决方案。
将给定的二叉树转换为双向链表 |设置 1
将给定的二叉树转换为双向链表 |设置 2
在这篇文章中,讨论了第三种解决方案,这似乎是最简单的。这个想法是按顺序遍历二叉树。在进行中序遍历时,在变量中跟踪先前访问过的节点,比如prev 。对于每个访问过的节点,将其设置为该节点的prev和prev旁边。
感谢 rahul、wishall 和所有其他读者对上述两篇文章的有用评论。
以下是该解决方案的实现。
C++
// A C++ program for in-place conversion of Binary Tree to DLL
#include
using namespace std;
/* A binary tree node has data, and left and right pointers */
struct node
{
int data;
node* left;
node* right;
};
// A simple recursive function to convert a given Binary tree to Doubly
// Linked List
// root --> Root of Binary Tree
// head --> Pointer to head node of created doubly linked list
void BinaryTree2DoubleLinkedList(node *root, node **head)
{
// Base case
if (root == NULL) return;
// Initialize previously visited node as NULL. This is
// static so that the same value is accessible in all recursive
// calls
static node* prev = NULL;
// Recursively convert left subtree
BinaryTree2DoubleLinkedList(root->left, head);
// Now convert this node
if (prev == NULL)
*head = root;
else
{
root->left = prev;
prev->right = root;
}
prev = root;
// Finally convert right subtree
BinaryTree2DoubleLinkedList(root->right, head);
}
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
node* newNode(int data)
{
node* new_node = new node;
new_node->data = data;
new_node->left = new_node->right = NULL;
return (new_node);
}
/* Function to print nodes in a given doubly linked list */
void printList(node *node)
{
while (node!=NULL)
{
cout << node->data << " ";
node = node->right;
}
}
/* Driver program to test above functions*/
int main()
{
// 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);
// Convert to DLL
node *head = NULL;
BinaryTree2DoubleLinkedList(root, &head);
// Print the converted list
printList(head);
return 0;
}
Java
// A Java program for in-place conversion of Binary Tree to DLL
// A binary tree node has data, left pointers and right pointers
class Node
{
int data;
Node left, right;
public Node(int data)
{
this.data = data;
left = right = null;
}
}
class BinaryTree
{
Node root;
// head --> Pointer to head node of created doubly linked list
Node head;
// Initialize previously visited node as NULL. This is
// static so that the same value is accessible in all recursive
// calls
static Node prev = null;
// A simple recursive function to convert a given Binary tree
// to Doubly Linked List
// root --> Root of Binary Tree
void BinaryTree2DoubleLinkedList(Node root)
{
// Base case
if (root == null)
return;
// Recursively convert left subtree
BinaryTree2DoubleLinkedList(root.left);
// Now convert this node
if (prev == null)
head = root;
else
{
root.left = prev;
prev.right = root;
}
prev = root;
// Finally convert right subtree
BinaryTree2DoubleLinkedList(root.right);
}
/* Function to print nodes in a given doubly linked list */
void printList(Node node)
{
while (node != null)
{
System.out.print(node.data + " ");
node = node.right;
}
}
// Driver program to test above functions
public static void main(String[] args)
{
// Let us create the tree as shown in above diagram
BinaryTree tree = new BinaryTree();
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);
// convert to DLL
tree.BinaryTree2DoubleLinkedList(tree.root);
// Print the converted List
tree.printList(tree.head);
}
}
// This code has been contributed by Mayank Jaiswal(mayank_24)
Python3
# Python program for conversion of
# binary tree to doubly linked list.
class Node:
def __init__(self, val):
self.right = None
self.data = val
self.left = None
class BtoDll:
def __init__(self):
self.head = None
self.tail = None
def convert(self, root):
# Base case
if root is None:
return
# Recursively convert left subtree
self.convert(root.left)
# Now convert this node
node = root
if self.head is None:
self.head = node
else:
self.tail.right = node
node.left = self.tail
self.tail = node
# Finally convert right subtree
self.convert(root.right)
return self.head
def BinaryTree2DoubleLinkedList(root):
'''
A simple recursive function to convert a given Binary tree
to Doubly Linked List
root --> Root of Binary Tree
'''
converter = BtoDll()
return converter.convert(root)
def print_dll(head):
'''Function to print nodes in given doubly linked list'''
while head is not None:
print(head.data, end=" ")
head = head.right
# Driver program to test above functions
if __name__ == "__main__":
# Let us create the tree as
# shown in above diagram
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)
# convert to DLL
head = BinaryTree2DoubleLinkedList(root)
# Print the converted list
print_dll(head)
# This code is contributed by codesankalp (SANKALP)
C#
// A C# program for in-place conversion
// of Binary Tree to DLL
using System;
// A binary tree node has data, left
// pointers and right pointers
public class Node
{
public int data;
public Node left, right;
public Node(int data)
{
this.data = data;
left = right = null;
}
}
class GFG
{
public Node root;
// head --> Pointer to head node of
// created doubly linked list
public Node head;
// Initialize previously visited node
// as NULL. This is static so that the
// same value is accessible in all
// recursive calls
public static Node prev = null;
// A simple recursive function to
// convert a given Binary tree
// to Doubly Linked List
// root --> Root of Binary Tree
public virtual void BinaryTree2DoubleLinkedList(Node root)
{
// Base case
if (root == null)
{
return;
}
// Recursively convert left subtree
BinaryTree2DoubleLinkedList(root.left);
// Now convert this node
if (prev == null)
{
head = root;
}
else
{
root.left = prev;
prev.right = root;
}
prev = root;
// Finally convert right subtree
BinaryTree2DoubleLinkedList(root.right);
}
/* Function to print nodes in a
given doubly linked list */
public virtual void printList(Node node)
{
while (node != null)
{
Console.Write(node.data + " ");
node = node.right;
}
}
// Driver Code
public static void Main(string[] args)
{
// Let us create the tree as
// shown in above diagram
GFG tree = new GFG();
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);
// convert to DLL
tree.BinaryTree2DoubleLinkedList(tree.root);
// Print the converted List
tree.printList(tree.head);
}
}
// This code is contributed by Shrikant13
Javascript
C++
Node * bToDLL(Node *root)
{
stack> s;
s.push({root, 0});
vector res;
bool flag = true;
Node* head = NULL;
Node* prev = NULL;
while(!s.empty()) {
auto x = s.top();
Node* t = x.first;
int state = x.second;
s.pop();
if(state == 3 or t == NULL) continue;
s.push({t, state+1});
if(state == 0) s.push({t->left, 0});
else if(state == 1) {
if(prev) prev->right = t;
t->left = prev;
prev = t;
if(flag) {
head = t;
flag = false;
}
}
else if(state == 2) s.push({t->right, 0});
}
return head;
}
输出:
25 12 30 10 36 15
请注意,不推荐使用上述静态变量(为简单起见,我们使用了静态变量)。想象一下为两棵或多棵树调用相同的函数的情况。 prev的旧值将在下一次调用不同的树时使用。为避免此类问题,我们可以使用双指针或指针引用。
时间复杂度:上述程序进行了简单的中序遍历,因此时间复杂度为 O(n),其中 n 是给定二叉树中的节点数。
下面的代码是上述中序遍历方法的直观迭代实现(灵感来自这个视频)——
C++
Node * bToDLL(Node *root)
{
stack> s;
s.push({root, 0});
vector res;
bool flag = true;
Node* head = NULL;
Node* prev = NULL;
while(!s.empty()) {
auto x = s.top();
Node* t = x.first;
int state = x.second;
s.pop();
if(state == 3 or t == NULL) continue;
s.push({t, state+1});
if(state == 0) s.push({t->left, 0});
else if(state == 1) {
if(prev) prev->right = t;
t->left = prev;
prev = t;
if(flag) {
head = t;
flag = false;
}
}
else if(state == 2) s.push({t->right, 0});
}
return head;
}
时间复杂度:O(N)
空间复杂度:O(N)