热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

将给定的二叉树转换为双链表|系列2

将给定的二叉树转换为双链表|系列2原文:https://w

将给定的二叉树转换为双链表 | 系列 2

原文:https://www.geeksforgeeks.org/convert-a-given-binary-tree-to-doubly-linked-list-set-2/

给定二叉树(BT),将其转换为双链表(DLL)。 节点中的左指针和右指针分别用作转换后的双链表中的上一个指针和下一个指针。 双链表中节点的顺序必须与给定二叉树的顺序相同。 有序遍历的第一个节点(BT 中最左边的节点)必须是双链表的头节点。

TreeToList

在这里讨论了此问题的解决方案。

在这篇文章中,讨论了另一个简单有效的解决方案。 这里讨论的解决方案有两个简单的步骤。](https://www.geeksforgeeks.org/in-place-convert-a-given-binary-tree-to-doubly-linked-list/)

1)固定左指针:在此步骤中,我们将左指针更改为指向双链表中的先前节点。 想法很简单,我们对树进行有序遍历。 在有序遍历中,我们跟踪先前访问的节点,并将左指针更改为先前的节点。 请参见以下实现中的fixPrevPtr()

2)固定右指针:上面的内容非常直观和简单。 如何更改指向双链表中下一个节点的右指针? 这个想法是使用在步骤 1 中固定的左指针。我们从二叉树(BT)的最右边的节点开始。 最右边的节点是双链表中的最后一个节点。 由于左指针已更改为指向双链表中的上一个节点,因此我们可以使用这些指针线性遍历整个双链表。 遍历将是从最后一个节点到第一个节点。 在遍历双链表时,我们跟踪先前访问的节点,并更改指向先前节点的右指针。 请参见以下实现中的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 tor right 
void printList(node *root) 
{ 
    while (root != NULL) 
    { 
        cout<<"\t"<<root->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 tor 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 tor 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


Python


# 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),
        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 nexr 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),
        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 "\n\t\t Inorder Tree Traversal\n"
inorder(root)
# Static variable pre for function fixPrevPtr
fixPrevPtr.pre = None
head = BTToDLL(root)
print "\n\n\t\tDLL Traversal\n"
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 tor 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

输出

Inorder Tree Traversal
25 12 30 10 36 15
DLL Traversal
25 12 30 10 36 15

时间复杂度:O(n),其中n是给定二叉树中的节点数。 该解决方案仅对所有二叉树节点进行两次遍历。

本文由 Bala 提供。 如果发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请发表评论


推荐阅读
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • Java 11相对于Java 8,OptaPlanner性能提升有多大?
    本文通过基准测试比较了Java 11和Java 8对OptaPlanner的性能提升。测试结果表明,在相同的硬件环境下,Java 11相对于Java 8在垃圾回收方面表现更好,从而提升了OptaPlanner的性能。 ... [详细]
  • 本文介绍了使用Python编写购物程序的实现步骤和代码示例。程序启动后,用户需要输入工资,并打印商品列表。用户可以根据商品编号选择购买商品,程序会检测余额是否充足,如果充足则直接扣款,否则提醒用户。用户可以随时退出程序,在退出时打印已购买商品的数量和余额。附带了完整的代码示例。 ... [详细]
  • 本文讲述了CodeForces1016C题目的解法。文章首先介绍了一种错误的理解,然后给出了正确的解法。其中,当位于一个角上时,有两种选择,一种是先一直走一行再返回来走,另一种是走到这一列的另一行上然后再往右走一列。作者给出了两种解法,一种是直接计算,一种是动态规划。最后,取两种解法的最优解作为答案。文章附上了源代码。 ... [详细]
  • 开源Keras Faster RCNN模型介绍及代码结构解析
    本文介绍了开源Keras Faster RCNN模型的环境需求和代码结构,包括FasterRCNN源码解析、RPN与classifier定义、data_generators.py文件的功能以及损失计算。同时提供了该模型的开源地址和安装所需的库。 ... [详细]
  • Python语法上的区别及注意事项
    本文介绍了Python2x和Python3x在语法上的区别,包括print语句的变化、除法运算结果的不同、raw_input函数的替代、class写法的变化等。同时还介绍了Python脚本的解释程序的指定方法,以及在不同版本的Python中如何执行脚本。对于想要学习Python的人来说,本文提供了一些注意事项和技巧。 ... [详细]
  • 本文讨论了一个数列求和问题,该数列按照一定规律生成。通过观察数列的规律,我们可以得出求解该问题的算法。具体算法为计算前n项i*f[i]的和,其中f[i]表示数列中有i个数字。根据参考的思路,我们可以将算法的时间复杂度控制在O(n),即计算到5e5即可满足1e9的要求。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
author-avatar
赵春柱_626
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有