zoukankan      html  css  js  c++  java
  • 将二叉搜索树转换为排序双向链表

    题目描述:有一个搜索二叉树,对于树中的任意一个节点,其左子树的所有值小于该节点的值,而其右子树的所有值大于该节点的值。要求:在不定义任何新的节点情况下,将该二叉树转换成为一个排序双向链表。

    假设有上面的二叉树,那么其转换为双向链表后的顺序应该为:2  3  4  5  6  7  8

    对于链表头节点:其直接前驱为空指针,直接后继为其父节点;

    对于链表尾节点:其直接前驱为其父节点,直接后继为空;

    对于左子树的根节点:其直接前驱为其左子树中的最大值;其直接后继为其右子树中的最小值或者父节点的值;

    对于右子树的根节点:其直接前驱为其左子树中的最大值或者父节点的值;其直接后继为右子树中的最大值;

    因此,我们可以将二叉树看作三个部分:根节点、左子树、右子树。

    如果我们可以递归地将左子树和右子树转换成为排序的双向链表,那么整个二叉树也就被转换成了排序的双向链表。

    示例代码如下:

    #include<iostream>
    using namespace std;
    
    struct BinTreeNode
    {
        int value;
        BinTreeNode *LeftNode;
        BinTreeNode *RightNode;
    };
    
    void ConvertNode(BinTreeNode *pNode, BinTreeNode **pLastNodeInList);
    
    BinTreeNode *Convert(BinTreeNode *pRootNode)
    {
        BinTreeNode *pLastNodeInList = nullptr;
        ConvertNode(pRootNode, &pLastNodeInList);
    
        BinTreeNode *pHeadOfList = pLastNodeInList;
        //此时pHeadOfList是二叉树的头节点,要返回链表头需要将它向左移,直到到达链表头
        while (pHeadOfList != nullptr&&pHeadOfList->LeftNode != nullptr)
        {
            pHeadOfList = pHeadOfList->LeftNode;
        }
        //返回链表的头节点
        return pHeadOfList;
    }
    
    void ConvertNode(BinTreeNode *pNode, BinTreeNode **pLastNodeInList)
    {
        if (pNode == nullptr)
        {
            return;
        }
        BinTreeNode *pCurrentNode = pNode;
        //如果存在左子树,那么递归地修改左子树节点指向
        if (pCurrentNode->LeftNode != nullptr){ ConvertNode(pNode->LeftNode, pLastNodeInList);}
        //将当前节点的左子节点指向链表尾部元素(因为链表尾部元素更小)
        pCurrentNode->LeftNode = *pLastNodeInList;
        //将链表尾部元素的右子节点指向当前节点,与上一步操作类似;
        if (*pLastNodeInList != nullptr){ (*pLastNodeInList)->RightNode = pCurrentNode; }
        //更新链表尾部元素
        *pLastNodeInList = pCurrentNode;
        //递归的修改右子树的节点指向
        if (pCurrentNode->RightNode != nullptr)
        { 
            ConvertNode(pCurrentNode->RightNode, pLastNodeInList); 
        }
    }
    int main()
    {}

    将上述代码对上面图示的二叉树进行转换,其转换过程中的变量变化如下,这能帮助我们理解整个转换的过程:

    在Convert函数中调用ConvertNode()函数结束以后,用来存储链表尾部元素的变量值为二叉树的根节点的值,即:10。

    因此,为了正确地返回链表头部元素,需要将该指针向左移到链表头地位置,最终将这个指针返回。

  • 相关阅读:
    JDBC第一部分
    java mysql学习第三部分
    java mysql 第六部分
    java mysql学习第五部分
    java mysql学习第二部分
    java mysql学习第一部分
    元注解
    改良之前写的模拟栈代码
    java中如何自定义异常
    java中的语法规则
  • 原文地址:https://www.cnblogs.com/puheng/p/9582025.html
Copyright © 2011-2022 走看看