二分查找与二叉排序树
二分查找
1. 二分查找
将 target 插入有序数组中,要求插入后数组仍然有序,返回插入位置的下标
int search(vector<int> &nums, int target) {
int index = -1;
int begin = 0;
int end = nums.size()-1;
while(index == -1) {
int mid = begin + end >> 1;
if(target == nums[mid]) index = mid;
else if(target > nums[mid]) {
if(mid + 1 == nums.size() || target < nums[mid+1]) index = mid + 1;
begin = mid + 1;
}
else {
if(mid == 0 || target > nums[mid-1]) index = mid;
end = mid - 1;
}
}
return index;
}
2. 区间查找
找到一串数中某个数在区间中的跨度
分别找到左右端点坐标
int left_bound(vector<int> &nums, int target) {
int begin = 0;
int end = nums.size() - 1;
while(begin <= end) {
int mid = begin + end >> 1;
if(target == nums[mid]) {
if(mid == 0 || target > nums[mid - 1]) return mid;
end = mid - 1;
}
else if(target > nums[mid]) begin = mid + 1;
else if(target < nums[mid]) end = mid - 1;
}
return -1;
}
int right_bound(vector<int> &nums, int target) {
int begin = 0;
int end = nums.size() - 1;
while(begin <= end) {
int mid = begin + end >> 1;
if(target == nums[mid]) {
if(mid == nums.size()-1 || target < nums[mid+1]) return mid;
begin = mid + 1;
}
else if(target > nums[mid]) begin = mid + 1;
else if(target < nums[mid]) end = mid - 1;
}
return -1;
}
3. 基于旋转数组的二分查找
int search(vector<int> &nums, int target) {
int begin = 0;
int end = nums.size() - 1;
while(begin <= end) {
int mid = (begin + end) / 2;
if (target == nums[mid]) { // 答案
return mid;
}
else if(target < nums[mid]) { // 情况 1
if(nums[begin] == nums[mid]) begin = mid + 1; // 特判如果只有两个元素的情况,小标为 0 1
else if(nums[begin] > nums[mid]) end = mid - 1;
else {
if(target >= nums[begin]) end = mid - 1;
else begin = mid + 1;
}
}
else if(target > nums[mid]) { // 情况 2
if(nums[begin] == nums[mid]) begin = mid + 1; // 特判
else if(nums[begin] < nums[mid]) begin = mid + 1;
else {
if(target < nums[begin]) begin = mid + 1;
else end = mid - 1;
}
}
}
return -1;
}
二叉查找(排序)树
查找数据结构,树上查找
二叉排序树性质: 每个节点的左子树节点的值一定小于等于该节点,右子树的节点大于等于该节点
中序遍历:从小到达
1. 插入节点
从根节点出发,通过比较 insert_node 与 node 的大小,寻找插入位置
void BST_insert(TreeNode *node, TreeNode *insert_node) {
if(insert_node->val < node->val) {
if(node->left) {
BST_insert(node->left, insert_node);
}
else node->left = insert_node;
}
else {
if(node->right) BST_insert(node->right, insert_node);
else node->right = insert_node;
}
}
2. 查找节点
bool BST_search(TreeNode *node, int value) {
if(node->val == value) return 1; // 找到
else if(node->val > value) { // 去左子树找
if(node->left) return BST_search(node->left, value);
return 0; // 没找到
}
else { // 去右子树找
if(node->right) return BST_search(node->right, value);
return 0;
}
}