数据结构与算法——二分查找与二叉查找树汇总整理

预备知识:二分查找基础知识

在列表A中查找B列表中元素是否存在,存在为1否则为0,结果存在result列表中。
递归实现:

#include <stdio.h>
#include <vector>

bool binary_search(std::vector<int>& sort_array,
 int begin, int end, int target) {
 if (begin > end) {
  return false;
 }
 int mid = (begin + end) / 2;
 if (target == sort_array[mid]) {
  return true;
 }
 else if (target < sort_array[mid]) {
  return binary_search(sort_array, begin, mid - 1, target);
 }
 else if (target > sort_array[mid]) {
  return binary_search(sort_array, mid + 1, end, target);
 }
}

std::vector<int> search_array(std::vector<int>& sort_array,
 std::vector<int>& random_array) {
 std::vector<int> result;
 for (int i = 0; i < random_array.size(); i++) {
  int res = binary_search(sort_array,0,sort_array.size() - 1,random_array[i]);
  result.push_back(res);
 }
 return result;
}

//在列表A中查找B列表中元素
int main() {
 int A[] = { -1, 2, 5, 20, 90, 100, 207, 800 };
 int B[] = { 50, 90, 3, -1, 207, 80 };
 std::vector<int> sort_array;
 std::vector<int> random_array;
 std::vector<int> C;
 for (int i = 0; i < 8; i++) {
  sort_array.push_back(A[i]);
 }
 for (int i = 0; i < 6; i++) {
  random_array.push_back(B[i]);
 }
 C = search_array(sort_array, random_array);
 for (int i = 0; i < C.size(); i++) {
  printf("%d\n", C[i]);
 }
 return 0;
}

循环实现

#include <stdio.h>
#include <vector>

bool binary_search(std::vector<int>& sort_array, int target) {
 int begin = 0;
 int end = sort_array.size() - 1;
 while (begin <= end) {
  int mid = (begin + end) / 2;
  if (target == sort_array[mid]) {
   return true;
  }
  else if (target < sort_array[mid]) {
   end = mid - 1;
  }
  else if (target > sort_array[mid]) {
   begin = mid + 1;
  }
 }
 return false;
}

std::vector<int> search_array(std::vector<int>& sort_array,
 std::vector<int>& random_array) {
 std::vector<int> result;
 for (int i = 0; i < random_array.size(); i++) {
  int res = binary_search(sort_array, random_array[i]);
  result.push_back(res);
 }
 return result;
}

int main() {
 int A[] = { -1, 2, 5, 20, 90, 100, 207, 800 };
 int B[] = { 50, 90, 3, -1, 207, 80 };
 std::vector<int> sort_array;
 std::vector<int> random_array;
 std::vector<int> C;
 for (int i = 0; i < 8; i++) {
  sort_array.push_back(A[i]);
 }
 for (int i = 0; i < 6; i++) {
  random_array.push_back(B[i]);
 }
 C = search_array(sort_array, random_array);
 for (int i = 0; i < C.size(); i++) {
  printf("%d\n", C[i]);
 }
 return 0;
}

例1:插入位置(easy) (二分查找)

在这里插入图片描述

class Solution {
public:
 int searchInsert(vector<int>& nums, int target) {
  int index = -1;
  int begin = 0;
  int end = nums.size() - 1;
  while (index == -1) {
   int mid = (begin + end) / 2;
   if (target == nums[mid]) {
    index = mid;
   }
   else if (target < nums[mid]) {
    if (mid == 0 || target > nums[mid - 1]) {
     index = mid;
    }
    end = mid - 1;
   }
   else if (target > nums[mid]) {
    if (mid == nums.size() - 1 || target < nums[mid + 1])
    {
     index = mid + 1;
    }
    begin = mid + 1;
   }
  }
  return index;
 }
};

例2:区间查找(medium)(二分查找)

在这里插入图片描述

#include <vector>

int left_bound(std::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]) {
   if (mid == 0 || nums[mid - 1] < target) {
    return mid;
   }
   end = mid - 1;
  }
  else if (target < nums[mid]) {
   end = mid - 1;
  }
  else if (target > nums[mid]) {
   begin = mid + 1;
  }
 }
 return -1;
}

int right_bound(std::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]) {
   if (mid == nums.size()-1 || nums[mid + 1] > target) {
    return mid;
   }
   begin = mid + 1;
  }
  else if (target < nums[mid]) {
   end = mid - 1;
  }
  else if (target > nums[mid]) {
   begin = mid + 1;
  }
 }
 return -1;
}

class Solution {
public:
 std::vector<int> searchRange(std::vector<int>& nums, int target) {
  std::vector<int> result;
  result.push_back(left_bound(nums, target));
  result.push_back(right_bound(nums, target));
  return result;
 }
};

例3:旋转数组查找(medium)(二分查找)

在这里插入图片描述

class Solution {
public:
 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]) {
    if (nums[begin] < nums[mid]) { //递增区间(正常做)
     if (target >= nums[begin]) {
      end = mid - 1;
     }
     else {
      begin = mid + 1;
     }
    }
    else if (nums[begin] > nums[mid]) {
     end = mid - 1;
    }
    else if (nums[begin] == nums[mid]) {
     begin = mid + 1;
    }
   }
   else if (target > nums[mid]) {
    if (nums[begin] < nums[mid]) {
     begin = mid + 1;
    }
    else if (nums[begin] > nums[mid]) {
     if (target >= nums[begin]) {
      end = mid - 1;
     }
     else {
      begin = mid + 1;
     }
    }
    else if (nums[begin] == nums[mid]) {
     begin = mid + 1;
    }
   }
  }
  return -1;
 }
};

预备知识:二叉查找(排序)树基础知识

在这里插入图片描述

#include <stdio.h>
#include <vector>

struct TreeNode {
 int val;
 TreeNode *left;
 TreeNode *right;
 TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

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;
  }
 }
}

void preorder_print(TreeNode *node,int layer){
 if (!node){
  return;
 }
 for (int i = 0; i < layer; i++){
  printf("-----");
 }
 printf("[%d]\n", node->val);
 preorder_print(node->left, layer + 1);
 preorder_print(node->right, layer + 1);
}

int main(){
 TreeNode root(8);
 std::vector<TreeNode *> node_vec;
 int test[] = {3, 10, 1, 6, 15};
 for (int i = 0; i < 5; i++){
  node_vec.push_back(new TreeNode(test[i]));
 }
 for (int i = 0; i < node_vec.size(); i++){
  BST_insert(&root, node_vec[i]);
 }
 preorder_print(&root, 0);
 return 0;
}

在这里插入图片描述

#include <stdio.h>
#include <vector>

struct TreeNode {
 int val;
 TreeNode *left;
 TreeNode *right;
 TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

bool BST_search(TreeNode *node, int value){
 if (node->val == value){
  return true;
 }
 if (value < node->val){
  if (node->left){
   return BST_search(node->left, value);
  }
  else{
   return false;
  }
 }
 else{
  if (node->right){
   return BST_search(node->right, value);
  }
  else{
   return false;
  }
 }
}

int main(){
 TreeNode a(8);
 TreeNode b(3);
 TreeNode c(10);
 TreeNode d(1);
 TreeNode e(6);
 TreeNode f(15);
 a.left = &b;
 a.right = &c;
 b.left = &d;
 b.right = &e;
 c.right = &f;
 for (int i = 0; i < 20; i++){
  if (BST_search(&a, i)){
   printf("%d is in the BST.\n", i);
  }
  else{
   printf("%d is not in the BST.\n", i);
  }
 }
 return 0;
}

例4:逆序数(hard)(二叉查找树应用)

在这里插入图片描述

#include <stdio.h>
#include <vector>

struct BSTNode {
 int val;
 int count;
 BSTNode* left;
 BSTNode* right;
 BSTNode(int x) : val(x), left(NULL), right(NULL), count(0) {}
};

void BST_insert(BSTNode* node, BSTNode* insert_node, int& count_small) {
 if (insert_node->val <= node->val) {
  node->count++;
  if (node->left) {
   BST_insert(node->left, insert_node, count_small);
  }
  else {
   node->left = insert_node;
  }
 }
 else {
  count_small += node->count + 1;
  if (node->right) {
   BST_insert(node->right, insert_node, count_small);
  }
  else {
   node->right = insert_node;
  }
 }
}

class Solution {
public:
 std::vector<int> countSmaller(std::vector<int>& nums) {
  std::vector<int> result;
  std::vector<BSTNode*> node_vec;
  std::vector<int> count;
  //将初始数组逆置
  for (int i = nums.size() - 1; i >= 0; i--) {
   node_vec.push_back(new BSTNode(nums[i]));
  }
  count.push_back(0);
  for (int i = 1; i < node_vec.size(); i++) {
   int count_small = 0;
   BST_insert(node_vec[0], node_vec[i], count_small);
   count.push_back(count_small);
  }
  for (int i = node_vec.size() - 1; i >= 0; i--) {
   delete node_vec[i];
   result.push_back(count[i]);
  }
  return result;
 }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小屋*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值