面试题36:转换二叉搜索树为排序双向链表

面试题36:转换二叉搜索树为排序双向链表

思路:
1、二叉排序树的特点:左子树的所有节点的值都比根节点的值大,右子树的所有节点的值都比根节点的值小;
2、根据这些特点,中序遍历二叉树就能得到有序的结果,所以通过中序遍历来转换这些结果。

代码:

//转换二叉搜索树为排序双向链表
TreeNode *convertBST(TreeNode *rootNode)
{
    if (rootNode == NULL)
    {
        return NULL;
    }

    TreeNode *pLastNode = NULL;

    convertBSTCore(rootNode, &pLastNode);

    while (pLastNode != NULL && pLastNode->leftchild != NULL)
    {
        pLastNode = (pLastNode)->leftchild;
    }

    return pLastNode;
}

void convertBSTCore(TreeNode *rootNode, TreeNode **pLastNode)
{
    if (rootNode == NULL)
    {
        return;
    }

    if (rootNode->leftchild != NULL)
    {
        convertBSTCore(rootNode->leftchild, pLastNode);
    }

    //convert
    rootNode->leftchild = *pLastNode;
    if (*pLastNode != NULL)
    {
        (*pLastNode)->rightChild = rootNode;
    }
    *pLastNode = rootNode;

    if (rootNode->rightChild != NULL)
    {
        convertBSTCore(rootNode->rightChild, pLastNode);
    }
}

非递归版本:

//非递归方式转换
void *convertBSTCore2(TreeNode *rootNode, TreeNode **pLastNode)
{
    if (rootNode == NULL)
    {
        return NULL;
    }
    *pLastNode = NULL;
    stack<TreeNode *> dataStack;
    dataStack.push(rootNode);

    while (!dataStack.empty())
    {
        TreeNode *currentNode = dataStack.top();
        if (currentNode->leftchild != NULL)
        {
            dataStack.push(currentNode->leftchild);
            //防止再次入栈
            currentNode->leftchild = NULL;
        }
        else
        {
            //convert
            currentNode->leftchild = *pLastNode;
            if ((*pLastNode) != NULL)
            {
                (*pLastNode)->rightChild = currentNode;
            }
            *pLastNode = currentNode;
            dataStack.pop();

            if (currentNode->rightChild != NULL)
            {
                dataStack.push(currentNode->rightChild);
                //防止再次入栈
                currentNode->rightChild = NULL;
            }
        }
    }
}

测试代码:

#include <iostream>
#include <stack>
#include <queue>
using namespace std;

typedef struct TreeNode
{
    int value;
    struct TreeNode *rightChild;
    struct TreeNode *leftchild;
} TreeNode, Node;

//添加子节点
TreeNode *addChild(TreeNode *root, int value, int direction);

//转换二叉搜索树为排序双向链表
TreeNode *convertBST(TreeNode *rootNode);

void convertBSTCore(TreeNode *rootNode, TreeNode **pHead);

void printTreeNodeInList(TreeNode *rootNode);

int main()
{
    TreeNode *tree1 = new TreeNode();
    tree1->value = 10;
    tree1->leftchild = tree1->rightChild = NULL;

    TreeNode *sn1 = addChild(tree1, 6, -1);
    TreeNode *sn2 = addChild(tree1, 14, 1);
    TreeNode *tn1 = addChild(sn1, 4, -1);
    TreeNode *tn2 = addChild(sn1, 8, 1);
    TreeNode *tn3 = addChild(sn2, 12, -1);
    TreeNode *tn4 = addChild(sn2, 16, 1);

    TreeNode *pHead = convertBST(tree1);
    printTreeNodeInList(pHead);
    return 0;
}

//添加子节点
TreeNode *addChild(TreeNode *root, int value, int direction)
{
    TreeNode *node = new TreeNode();
    node->value = value;
    node->leftchild = node->rightChild = NULL;

    if (direction == 1)
    {
        root->rightChild = node;
    }
    if (direction == -1)
    {
        root->leftchild = node;
    }

    return node;
}

void printTreeNodeInList(TreeNode *rootNode)
{
    TreeNode *pNode = rootNode;
    while (pNode != NULL)
    {
        cout << pNode->value;
        pNode = pNode->rightChild;

        if (pNode != NULL)
        {
            cout << ",";
        }
    }
    cout << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值