36 二叉搜索树与双向链表

题目

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。比如输入下图中左边的二叉搜索树,则输出转换之后的排序双向链表。

牛客网 OJ
[AcWing OJ

C 语言题解

中序遍历,递归实现:

void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList);

BinaryTreeNode* Convert(BinaryTreeNode* pRootOfTree)
{
    BinaryTreeNode *pLastNodeInList = NULL;
    ConvertNode(pRootOfTree, &pLastNodeInList);

    // pLastNodeInList指向双向链表的尾结点,
    // 我们需要返回头结点
    BinaryTreeNode *pHeadOfList = pLastNodeInList;
    while (pHeadOfList != NULL && pHeadOfList->m_pLeft != NULL)
        pHeadOfList = pHeadOfList->m_pLeft;

    return pHeadOfList;
}

void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList)
{
    if (pNode == NULL)
        return;

    BinaryTreeNode *pCurrent = pNode;

    if (pCurrent->m_pLeft != NULL)
        ConvertNode(pCurrent->m_pLeft, pLastNodeInList);

    pCurrent->m_pLeft = *pLastNodeInList;
    if (*pLastNodeInList != NULL)
        (*pLastNodeInList)->m_pRight = pCurrent;

    *pLastNodeInList = pCurrent;

    if (pCurrent->m_pRight != NULL)
        ConvertNode(pCurrent->m_pRight, pLastNodeInList);
}

C++ 题解

借助栈实现:

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        TreeNode* pre = nullptr;
        TreeNode* head = nullptr;
        
		// 定义一个栈
        stack<TreeNode*> s;
        
        while(pRootOfTree || !s.empty())
        {
			// 先遍历到树最左的节点,依次压入栈中
            while(pRootOfTree)
            {
                s.push(pRootOfTree);
                pRootOfTree = pRootOfTree->left;
            }
            
            if(!s.empty())
            {
                pRootOfTree = s.top();
                s.pop();
                
                if(pre != nullptr)
                {
                    // 串联双向链表
                    pRootOfTree->left = pre;
                    pre->right = pRootOfTree;
                }
                else
                {
                    // pre == nullptr 说明此时是第一个结点
                    head = pRootOfTree;
                }
                
                // 链表前进
                pre = pRootOfTree;
                // 树节点前进
                pRootOfTree = pRootOfTree->right;
            }
        }
        
        return head;        
    }
};

python 题解

中序遍历树的节点存放在一个列表中,遍历列表增加双向链表的指向:

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Convert(self, pRootOfTree):
        # write code here
        if pRootOfTree == None:
            return 
        
        self.attr = []
        # 得到树的中序递归序列
        self.inOrder(pRootOfTree)
        
        # 遍历树的中序序列,增加双向链表的互指
        for i,v in enumerate(self.attr[:-1]):
            v.right = self.attr[i+1]
            self.attr[i+1].left = v
        
        # 注意self.attr存放的是链表节点
        return self.attr[0]
    
    # 递归版树的中序遍历
    def inOrder(self,pRoot):
        if pRoot == None:
            return 
        self.inOrder(pRoot.left)
        self.attr.append(pRoot)
        self.inOrder(pRoot.right)
posted @ 2019-01-31 09:26  youngliu91  阅读(99)  评论(0)    收藏  举报