二叉搜索树与中序遍历的缘分

二叉搜索树一个很重要的特性就是:树中任何结点的左子树中所有结点的值均比该结点小,右子树中所有结点的值均比该结点大。对二叉搜索树进行中序遍历即得到一个递增排序的序列。

检查一个树是否是二叉搜索树可以使用中序遍历,根据递增排序的序列生成二权搜索树也可以使用中序遍历。往往使用中序遍历来解决二叉搜索树的问题时可以得到最优的时间复杂度(不考虑递归的时间损耗)。解决这两个问题,在遍历的过程中都需要记录与目前位置相关的信息。

1、检查一个树是否是二叉搜索树。

98. Validate Binary Search Tree

使用中序遍历来解决。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isValidBST(TreeNode *root) {
        if(!root) return true;
        return (isValidBST(root->left) && isValidVal(root->val) && isValidBST(root->right)); //中序遍历
    }
private:
    bool isValidVal(int val) {
        if(bFirstNode) {
            bFirstNode = false;
            prevNodeVal = val;
            return true;
        }

        if(prevNodeVal >= val) return false;

        prevNodeVal = val;
        return true;
    }

    bool bFirstNode = true;
    int prevNodeVal = 0; //记录前一个结点的值
};

2、根据递增排序的序列生成二权搜索树。

109. Convert Sorted List to Binary Search Tree

使用中序遍历来解决。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *sortedListToBST(ListNode *head) {
        list = head;
        return listToBST(getListLength(head));
    }
private:
    int getListLength(ListNode *node) {
        int length = 0;
        while(node) {
            ++length;
            node = node->next;
        }
        return length;
    }
    TreeNode *listToBST(int n) { //中序遍历
        if(n == 0) return NULL;
        TreeNode *pNode = new TreeNode(0);
        pNode->left = listToBST(n / 2); //左子树共(n / 2)个结点
        pNode->val = list->val;
        list = list->next;
        pNode->right = listToBST(n - n / 2 - 1); //右子树共(n - n / 2 - 1)个结点
        return pNode;
    }

    ListNode *list; //记录当前位置
};