二叉搜索樹一個很重要的特性就是:樹中任何結點的左子樹中所有結點的值均比該結點小,右子樹中所有結點的值均比該結點大。對二叉搜索樹進行中序遍歷即得到一個遞增排序的序列。
檢查一個樹是否是二叉搜索樹可以使用中序遍歷,根據遞增排序的序列生成二權搜索樹也可以使用中序遍歷。往往使用中序遍歷來解決二叉搜索樹的問題時可以得到最優的時間復雜度(不考慮遞歸的時間損耗)。解決這兩個問題,在遍歷的過程中都需要記錄與目前位置相關的信息。
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; //記錄當前位置
};