牛客网剑指Offer——二叉搜索树与双向链表

题目描述

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

题目分析

  • 二叉树中每个节点都有两个指向子节点的指针;
  • 在双向链表中,每个节点也有两个指针,分别指向前一个节点和后一个节点;
  • 在将二叉树转换成双向链表时,原先指向左子节点的指针调整为链表中指向前一个节点的指针,原先指向右子节点的指针调整为链表中指向后一个节点的指针。


概念

1、二叉搜索树:

二叉搜索树(英语:Binary Search Tree),也称二叉查找树、有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree),是指一棵空树或者具有下列性质的二叉树:

  • 任意节点,如果左子树不为空,则左子树上所有结点的值均小于它的根结点的值;
  • 任意节点,如果右子树不为空,则右子树上所有结点的值均大于它的根结点的值;
  • 任意节点的左、右子树也分别为二叉查找树;
  • 没有键值相等的节点。

解题思路

由于二叉搜索树的特点,可以看出其中序遍历的结果是从小到大访问节点的,正好符合链表有序的要求,所以可以借助中序遍历的过程来完成二叉树到链表的转换过程,可以采用递归进行处理。

每次在递归遍历的时候设置一个pre,记录中序遍历时当前访问节点(node)的前一个节点,然后将当前节点的左指针指向pre,然后如果pre节点不为空则将pre的右节点指向当前节点,由此就形成了一个双向链表的前后指针。每次递归重复这两步,则可以形成一个完整的双向链表。最后一步就是双向链表已经构建完成了,而题目要求返回双向链表,则往前遍历找到双向链表的头返回即可。


代码

/*
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)
    {
        if( pRootOfTree == NULL )
            return NULL;
        help( pRootOfTree );
        while( pre->left != NULL )
            pre = pre->left;
        return pre;
    }
    TreeNode* pre = NULL;
    void help( TreeNode* node )
    {
        if( node == NULL )
            return;
        
        if( pre == NULL && node->left == NULL )
            pre = node;
        
        help( node->left );
        if( pre != NULL && pre != node )
        {
            // pre为上一个节点,node为当前节点
            pre->right = node;
            node->left = pre;
            pre = node;
        }
        help(node->right);
        return;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_36132127/article/details/80231578