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。

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

  • 相关阅读:
    IntelliJ IDEA 14.03 java 中文文本处理中的编码格式设置
    应聘感悟
    STL string分析
    CUDA SDK VolumeRender 分析 (1)
    BSP
    CUDA SDK VolumeRender 分析 (3)
    CUDA SDK VolumeRender 分析 (2)
    Windows软件发布时遇到的一些问题
    Ten Commandments of Egoless Programming (转载)
    复习下光照知识
  • 原文地址:https://www.cnblogs.com/puheng/p/9582025.html
Copyright © 2011-2022 走看看