美文网首页
二分查找与二叉排序树

二分查找与二叉排序树

作者: 编程半岛 | 来源:发表于2018-09-05 13:02 被阅读62次

二分查找

1.搜索插入位置

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

2. 在排序数组中查找元素的第一个和最后一个位置

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

3. 搜索旋转排序数组


二叉查找树

4. 序列化和反序列化二叉搜索树

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string result = "";
        preOrder(root, result);
        return result;
    }
    
    void preOrder(TreeNode* node, string& str)
    {
        if( !node )
        {
            return ;
        }
        string temp = "";
        int_to_string(node->val, temp);
        str += temp;
        preOrder(node->left, str);
        preOrder(node->right, str);
    }
    
    void int_to_string(int value, string& str)      // 整形转字符型
    {
        string temp = "";
        while(value)
        {
            temp += value % 10 + '0';
            value /= 10;
        }
        
        for(int i=temp.length()-1; i>=0; --i)
        {
            str += temp[i];
        }
        
        str += '#';
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        if( data.length() == 0 )
        {
            return NULL;
        }
        
        vector<TreeNode*> vec_tree;
        
        int value = 0;
        for(int i=0; i<data.length(); ++i)
        {
            if( data[i] == '#' )                            // 拆分字符串
            {
                vec_tree.push_back(new TreeNode(value));
                value = 0;
            }
            else                                            // 字符串转数字
            {
                value = value*10 + (data[i] - '0');
            }
        }
        
        for(int i=1; i<vec_tree.size(); ++i)                // 构建二叉搜索树
        {
            BST(vec_tree[0], vec_tree[i]);
        }
        
        return vec_tree[0];
    }
    
    void BST(TreeNode* node, TreeNode* insert_node)         // 二叉搜索树的插入
    {        
        if( insert_node->val < node->val)
        {
            if( node->left )
            {
                BST(node->left, insert_node);
            }
            else
            {
                node->left = insert_node;
            }
        }
        else
        {
            if( node->right )
            {
                BST(node->right, insert_node);
            }
            else
            {
                node->right = insert_node;
            }
        }
    }

};

// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));

5.计算右侧小于当前元素的个数

class Solution {

struct BSTNode
{
    int val;            
    int count;          // 统计左结点的个数
    BSTNode* left;
    BSTNode* right;
    BSTNode(int value) : val(value), count(0), left(NULL), right(NULL) {}
};
    
public:
    vector<int> countSmaller(vector<int>& nums) {
        vector<int> result;        
        vector<BSTNode*> bst;       // 构建的bst树
        vector<int> count;
        
        if( nums.size() == 0 )
        {
            return result;
        }
        
        for(int i=nums.size()-1; i>=0; --i)     // 初始化bst树
        {        
            bst.push_back(new BSTNode(nums[i]));
        }
        
        count.push_back(0);
        for(int i=1; i<bst.size(); ++i)
        {
            int count_small = 0;
            bst_insert(bst[0], bst[i], count_small);
            count.push_back(count_small);
        }
        
        for(int i=count.size()-1; i>=0; --i)
        {
            result.push_back(count[i]);
            delete bst[i];
        }
        
        return result;
    }
    
    void bst_insert(BSTNode* node, BSTNode* insert_node, int& count)
    {
        if( insert_node->val <= node->val )
        {
            node->count++;
            if( node->left )
            {
                bst_insert(node->left, insert_node, count);
            }
            else
            {
                node->left = insert_node;
            }
        }
        else
        {
            count += node->count + 1;
            if( node->right )
            {
                bst_insert(node->right, insert_node, count);
            }
            else
            {
                node->right = insert_node;
            }
        }
    }
};

相关文章

  • 数据结构--查找

    查找分类 有序查找(二分查找、插值查找、斐波拉契查找) 线性索引查找 二叉排序树 散列表

  • 查找

    查找一般要掌握顺序查找、二分查找、哈希表查找和二叉排序树查找。要能够快速准确地写出二分查找的代码。 1. 顺序查找...

  • 查找

    二分查找适用于有序表查找, 包括二叉排序树 散列查找请看本博客数据结构与算法hash表文章http://www.j...

  • 2.4.2 查找和排序

    排序 复习1:冒泡排序 复习2:快速排序 查找 1)顺序查找2)二分查找 3)哈希表查找4)二叉排序树查找

  • 算法和数据结构(一)—— 查找和排序

    查找和排序都是程序设计中经常用到的算法。查找相对而言较为简单,不外乎顺序查找、二分查找、哈希表查找和二叉排序树查找...

  • python二分查找算法

    文章概述 二分查找法介绍 简单查找与二分查找对比 二分查找  二分查找算法主要思想:在有序列表中查找指定元素,先从...

  • 动画 | 什么是二分搜索树(二叉查找树)?

    二分搜索树属性 二分搜索树的又名比较多,有的叫二叉排序树,也有的叫二叉查找树,或者有序二叉查找树。是指一棵空树或者...

  • 散列表查找

    散列技术   散列技术的方法指的是不同于顺序查找、二分查找、二叉排序树及B-树上的查找。它不以关键字的比较为基本操...

  • 2.3 二分查找的递归与非递归实现

    Chapter2: 时间复杂度分析、递归、查找与排序 3. 二分查找的递归与非递归实现 二分查找即折半查找,为查找...

  • 2.3 二分查找的递归与非递归实现

    Chapter2: 时间复杂度分析、递归、查找与排序 3. 二分查找的递归与非递归实现 二分查找即折半查找,为查找...

网友评论

      本文标题:二分查找与二叉排序树

      本文链接:https://www.haomeiwen.com/subject/zsejiftx.html