将给定的二叉树转换为双向链表 |设置 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 是给定二叉树中的节点数。该解决方案只是对所有二叉树节点进行两次遍历。