查找算法

深度解密Go语言之map

自作多情 提交于 2020-01-08 08:51:52
目录 什么是 map 为什么要用 map map 的底层如何实现 map 内存模型 创建 map 哈希函数 key 定位过程 map 的两种 get 操作 如何进行扩容 map 的遍历 map 的赋值 map 的删除 map 进阶 可以边遍历边删除吗 key 可以是 float 型吗? 总结 参考资料 这篇文章主要讲 map 的赋值、删除、查询、扩容的具体执行过程,仍然是从底层的角度展开。结合源码,看完本文一定会彻底明白 map 底层原理。 我要说明的是,这里对 map 的基本用法涉及比较少,我相信可以通过阅读其他入门书籍了解。本文的内容比较深入,但是由于我画了各种图,我相信很容易看懂。 什么是 map 维基百科里这样定义 map: In computer science, an associative array, map, symbol table, or dictionary is an abstract data type composed of a collection of (key, value) pairs, such that each possible key appears at most once in the collection. 简单说明一下:在计算机科学里,被称为相关数组、map、符号表或者字典,是由一组 <key, value>

查找两个有序数组的中位数

假如想象 提交于 2020-01-08 05:29:56
题目: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 。 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。 你可以假设 nums1 和 nums2 不会同时为空。 示例 1: nums1 = [1, 3] nums2 = [2] 则中位数是 2.0 class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { int sum=nums1.length+nums2.length; int[] a=new int[sum]; double mid=0.0d; for(int i=0;i<nums1.length;i++) { a[i]=nums1[i]; } for(int i=0;i<nums2.length;i++) { a[nums1.length+i]=nums2[i]; } Arrays.sort(a); mid=sum%2==1?(double)a[sum/2]:(a[sum/2-1]+a[sum/2])/2.0f; return mid; } } 上式的方法虽然实现了算法要求,但是时间复杂度却没有达到; 来源: https://www.cnblogs.com/Optimism/p/10719957.html

图解:二叉搜索树算法(BST)

僤鯓⒐⒋嵵緔 提交于 2020-01-07 12:31:09
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “岁月极美,在于它必然的流逝” “春花 秋月 夏日 冬雪” — 三毛 一、树 & 二叉树 树 是由节点和边构成,储存元素的集合。节点分根节点、父节点和子节点的概念。 如图:树深=4; 5是根节点;同样8与3的关系是父子节点关系。 二叉树binary tree ,则加了“二叉”(binary),意思是在树中作区分。每个节点至多有两个子(child),left child & right child。二叉树在很多例子中使用,比如二叉树表示算术表达式。 如图:1/8是左节点;2/3是右节点; 二、二叉搜索树 BST 顾名思义,二叉树上又加了个搜索的限制。其要求:每个节点比其左子树元素大,比其右子树元素小。 如图:每个节点比它左子树的任意节点大,而且比它右子树的任意节点小 三、BST Java实现 直接上代码,对应代码分享在 Github 主页 BinarySearchTree.java package org.algorithm.tree; /* * Copyright [2015] [Jeff Lee] * * Licensed under the Apache License, Version 2.0 (the

数据结构学习笔记(0X08)--散列表

余生长醉 提交于 2020-01-07 08:29:50
一、散列表的由来? 1.散列表来源于数组,它借助散列函数对数组这种数据结构进行扩展,利用的是数组支持按照下标随机访问元素的特性。 2.需要存储在散列表中的数据我们称为键,将键转化为数组下标的方法称为散列函数,散列函数的计算结果称为散列值。 3.将数据存储在散列值对应的数组下标位置。 二、如何设计散列函数? 总结3点设计散列函数的基本要求 1.散列函数计算得到的散列值是一个非负整数。 2.若key1=key2,则hash(key1)=hash(key2) 3.若key≠key2,则hash(key1)≠hash(key2) 正是由于第3点要求,所以产生了几乎无法避免的散列冲突问题。 三、散列冲突的解放方法? 1.常用的散列冲突解决方法有2类:开放寻址法(open addressing)和链表法(chaining) 2.开放寻址法 ①核心思想:如果出现散列冲突,就重新探测一个空闲位置,将其插入。 ②线性探测法(Linear Probing): 插入数据:当我们往散列表中插入数据时,如果某个数据经过散列函数之后,存储的位置已经被占用了,我们就从当前位置开始,依次往后查找,看是否有空闲位置,直到找到为止。 查找数据:我们通过散列函数求出要查找元素的键值对应的散列值,然后比较数组中下标为散列值的元素和要查找的元素是否相等,若相等,则说明就是我们要查找的元素;否则,就顺序往后依次查找

Red Black Tree 红黑树 AVL trees 2-3 trees 2-3-4 trees B-trees Red-black trees Balanced search tree 平衡搜索树

点点圈 提交于 2020-01-04 03:02:56
小结: 1、红黑树:典型的用途是实现 关联数组 2、旋转 当我们在对红黑树进行插入和删除等操作时,对树做了修改,那么可能会违背红黑树的性质。 为了保持红黑树的性质,我们可以通过对树进行旋转,即修改树中某些结点的颜色及指针结构,以达到对红黑树进行插入、删除结点等操作时,红黑树依然能保持它特有的性质(五点性质)。 https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-046j-introduction-to-algorithms-sma-5503-fall-2005/video-lectures/lecture-10-red-black-trees-rotations-insertions-deletions/lec10.pdf Balanced search trees Balanced search tree: A search-tree data structure for which a height of O(lg n) is guaranteed when implementing a dynamic set of n items. AVL trees 2-3 trees 2-3-4 trees B-trees Red-black trees 【1】 Example of a

HashMap、lru、散列表

北战南征 提交于 2020-01-01 10:21:05
HashMap HashMap的数据结构:HashMap实际上是一个数组和链表(“链表散列”)的数据结构。底层就是一个数组结构,数组中的每一项又是一个链表。 hashCode是一个对象的标识,Java中对象的hashCode是一个int类型值。通过hashCode来算出指定数组的索引可以快速定位到要找的对象在数组中的位置,之后再遍历链表找到对应值,理想情况下时间复杂度为O(1),并且不同对象可以拥有相同的hashCode(hash碰撞)。发生碰撞后会把相同hashcode的对象放到同一个链表里,但是在数组大小不变的情况下,存放键值对越多,查找的时间效率也会降低 扩容可以解决该问题,而负载因子决定了什么时候扩容,负载因子是已存键值对的数量和总的数组长度的比值。默认情况下负载因子为0.75,我们可在初始化HashMap的时候自己修改。阀值 = 当前数组长度✖负载因子 hashmap中默认负载因子为0.75,长度默认是16,默认情况下第一次扩容判断阀值是16 ✖ 0.75 = 12;所以第一次存键值对的时候,在存到第13个键值对时就需要扩容了,变成16X2=32。 put流程 对key hash,二次hash,hash扰乱函数,减少hash碰撞 int hash(Object key) { int h = key.hashCode(); return (h ^ (h >>> 16)) &

MySQL数据库(5)- pymysql的使用、索引

眉间皱痕 提交于 2020-01-01 07:27:33
一、pymysql模块的使用 1、pymysql的下载和使用 之前我们都是通过MySQL自带的命令行客户端工具mysql来操作数据库,那如何在python程序中操作数据库呢?这就需要用到pymysql模块,该模块本质就是一个套接字客户端软件,使用前需要事先安装。 1)pymysql模块的下载 pip3 install pymysql 2)pymysql模块的使用 现有数据库mydb,其中有一个userinfo表,表中数据如下: mysql> select * from userinfo; +----+------+-----+ | id | name | pwd | +----+------+-----+ | 1 | wll | 123 | | 2 | ssx | 456 | +----+------+-----+ 示例:使用Python实现用户登录,如果用户存在则登录成功,否则登录失败 import pymysql username = input('请输入用户名:') pwd = input('请输入密码:') # 1、连接 conn = pymysql.connect( host = '127.0.0.1', port = 3306, user = 'root', password = '123', db = 'mydb', charset = 'utf8' ) # 2

数据库索引

旧街凉风 提交于 2020-01-01 04:22:24
以下索引知识以mysql索引来阐述 一:MySQL中索引的语法   (1)创建索引 --在创建表的时候添加索引 CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX [indexName] (username(length)) ); --在创建表以后添加索引 ALTER TABLE my_table ADD [UNIQUE] INDEX index_name(column_name); --或者 CREATE INDEX index_name ON my_table(column_name); 注意: 1、索引需要占用 磁盘空间 ,因此在创建索引时要考虑到磁盘空间是否足够 2、创建索引时需要 对表加锁 ,因此实际操作中需要在业务空闲期间进行    (2)索引相关sql --删除索引 DROP INDEX my_index ON tablename; --或者 ALTER TABLE table_name DROP INDEX index_name; --查看表中的索引 SHOW INDEX FROM tablename --查看查询语句使用索引的情况 //explain 加查询语句 explain SELECT * FROM table_name WHERE column_1='123

(七)MySQL索引和执行计划

不羁岁月 提交于 2020-01-01 04:22:05
索引 和 EXPLAIN/DESC 概念 索引 是对 数据库 表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息 索引分为聚簇索引和非聚簇索引两种 聚簇索引是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快 MyISAM:非聚簇索引 非聚簇索引的 主索引和辅助索 引几乎是一样的,只是主索引不允许重复,不允许空值,他们 的叶子结点的key都存储指向键值对应的数据的物理地址 非聚簇索引的数据表和索引表是分开存储的 非聚簇索引中的数据是根据数据的插入顺序保存。因此非聚簇索引更适合单个数据的查询。插入顺序不受键值影响 只有在MyISAM中才能使用FULLTEXT索引 InnoDB:聚簇索引 聚簇索引的 主索引的叶子结点存储的是键值对应的数据本身,辅助索引的叶子结点存储的是键值对应的数据的主键键值 。因此主键的值长度越小越好,类型越简单越好 聚簇索引的数据和主键索引存储在一起。 聚簇索引的数据是根据主键的顺序保存。因此适合按主键索引的区间查找,可以有更少的磁盘I/O,加快查询速度。但是也是因为这个原因,聚簇索引的插入顺序最好按照主键单调的顺序插入,否则会频繁的引起页分裂,严重影响性能。 在InnoDB中

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

大兔子大兔子 提交于 2019-12-30 23:06:54
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 你的算法时间复杂度必须是 O(log n) 级别。 如果数组中不存在目标值,返回 [-1, -1]。 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: [3,4] 示例 2: 输入: nums = [5,7,7,8,8,10], target = 6 输出: [-1,-1] class Solution { public: vector<int> searchRange(vector<int>& nums, int target) { int left=0,right=nums.size(),mid; vector<int> res; while(left<right){ //找左边界 mid=left+(right-left)/2; if(nums[mid]==target) right=mid; else if(nums[mid]<target) left=mid+1; else right=mid; } if(left==nums.size()||nums[left]!=target) return res={-1,-1}; if(nums[left]==target) res.emplace_back(left);