二元查找树转变成排序的双向链表

本文介绍如何将二叉查找树转换为排序的双向链表,通过中序遍历的方法实现转换,并提供了递归与非递归两种实现方式。

把二元查找树转变成排序的双向链表
题目:
输入一棵二元查找树,将该转换成个排 序的双向链表。
要求不能创建任何新的结点,只调整指针向。
     10
    /   \
   6   14
  / \   / \
 4 8 12 8
转换成双向链表
4=6=8=10=12=14=16

 

利用中序遍历来解决比较简单,这里我主要提供一种非递归版本来解决这个问题

递归版本:(copy自http://blog.youkuaiyun.com/wcyoot/article/details/6428297

template<typename T>
struct TreeNode
{
    T data;
    TreeNode* pLChild;
    TreeNode* pRChild;
};

// 要求两个输出参数要初始化为NULL  
template<typename T>
void ConvertBSTree2List(TreeNode<T>* pTreeRoot/*树的根节点*/, TreeNode<T>*& pListHead/*双向链表的头指针*/, TreeNode<T>*& pListLast/*双向链表的尾指针*/)
{
    if (pTreeRoot == NULL)
    {
        return;
    }

    // 中序遍历左子树  
    ConvertBSTree2List(pTreeRoot->pLChild, pListHead, pListLast);

    // 处理当前节点,把节点链到双向链表尾部  

    // 修改当前节点左指针,指向双向链表尾部  
    pTreeRoot->pLChild = pListLast;
    if (pListLast)       // 非第一个节点  
    {
        pListLast->pRChild = pTreeRoot;
    }
    else                // 第一个节点  
    {
        pListHead = pTreeRoot;
    }

    pListLast = pTreeRoot;

    // 中序遍历右子树  
    ConvertBSTree2List(pTreeRoot->pRChild, pListHead, pListLast);
}

非递归版本:(如果对iteration遍历二叉树方法不清楚,可以参考二叉树的前序、中序、后序遍历非递归实现

 

TreeNode* turnTreeToDLinkList(TreeNode *root)
{
    TreeNode *head = root;
    if (head == nullptr)
        return head;
    stack<TreeNode*> sta;
    sta.push(root);
    TreeNode* lastRoot = root;
    TreeNode *preNode = nullptr;
    while (!sta.empty())
    {
        root = sta.top();
        if (lastRoot != root->right)
        {
            if (lastRoot != root->left) {
                if (root->left != nullptr) {
                    sta.push(root->left);
                    continue;
                }
            }
            root->left = preNode;
            if (preNode)
                preNode->right = root;
            else
                head = root;
            preNode = root;
            if (root->right != nullptr) {
                sta.push(root->right);
                continue;
            }
        }
        lastRoot = root;
        sta.pop();
    }
    return head;
}

 

转载于:https://www.cnblogs.com/sdlwlxf/p/5225003.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值