算法

java算法- B-Tree和B+Tree(个人整理,实用版)

寵の児 提交于 2020-01-07 20:42:58
一、介绍 B+树索引是B+树在 数据库 中的一种实现,是最常见也是数据库中使用最为频繁的一种索引。 B+树中的B代表平衡(balance)。( 平衡多路查找树 ) B+树是从最早的平衡二叉树演化而来的。 二、B-Tree B-Tree是为 磁盘 等外存储设备设计的一种平衡查找树。 每个节点最多有m个孩子。 除了根节点和叶子节点外,其它每个节点至少有Ceil(m/2)个孩子。 若根节点不是叶子节点,则至少有2个孩子 所有叶子节点都在同一层,且不包含其它关键字信息 每个非终端节点包含n个关键字信息(P0,P1,…Pn, k1,…kn) 关键字的个数n满足:ceil(m/2)-1 <= n <= m-1 ki(i=1,…n)为关键字,且关键字升序排序。 Pi(i=1,…n)为指向子树根节点的指针。P(i-1)指向的子树的所有节点关键字均小于ki,但都大于k(i-1) (个人理解:关键字上的数据存储在本节点上,每个范围内的数据存储在下一个节点上,叶子节点只存储数据) 如果data数据较大时将会导致每个节点(即一个页)能存储的key的数量很小,当存储的数据量很大时同样会导致B-Tree的深度较大,进而影响查询效率。 原文 https://blog.csdn.net/baidu_29961857/article/details/89879739 package com.numberone

Redis研究-3.1 数据结构之链表

空扰寡人 提交于 2020-01-07 18:21:21
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 我们知道,数据结构中,链表的最大好处就是能高效的实现动态增、删、改,缺点就是遍历访问比较慢,因此,在Redis中,很多功能的底层实现都是基于链表的,因为Redis是基于C语言来写的,所以只能自己实现自己的链表结构。对于一个常规的双向链表节点,我们通常使用下面的方式来定义: typedef struct Node{ void *value; struct Node *prev; struct Node *next; }Node; Redis中,在adlist.h中也是这样子定义的 typedef struct listNode { // 前置节点 struct listNode *prev; // 后置节点 struct listNode *next; // 节点的值 void *value; } listNode; 上面的node定义就是链表的每个元素了。在Redis中,同时定义了一个双向链表,并给这个链表定义了三个操作函数(方法): typedef struct list { // 表头节点 listNode *head; // 表尾节点 listNode *tail; // 节点值复制函数 void *(*dup)(void *ptr); // 节点值释放函数 void (*free)(void *ptr)

面试问有哪几种垃圾回收算法,再也不怕了!

本小妞迷上赌 提交于 2020-01-07 16:37:52
可以从不同的的角度去划分垃圾回收算法: 一、按照基本回收策略分初级篇 引用计数(Reference Counting): 比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只用收集计数为0的对象。此算法最致命的是无法处理循环引用的问题。 标记-清除(Mark-Sweep): 此算法执行分两阶段。第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。此算法需要暂停整个应用,同时,会产生内存碎片。 复制(Copying): 此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。 次算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不会出现“碎片”问题。当然,此算法的缺点也是很明显的,就是需要两倍内存空间。 标记-整理(Mark-Compact): 此算法结合了“标记-清除”和“复制”两个算法的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把清除未标记对象并且把存活对象“压缩”到堆的其中一块,按顺序排放。 此算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。 二、按分区对待的方式分 增量收集(Incremental Collecting

算法经典问题(一)

落爺英雄遲暮 提交于 2020-01-07 16:11:05
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 求阶梯数 在你面前有一条长长的阶梯,如果你每次跨两阶,那么最后剩余一阶,如果你每次跨三阶,那么最后剩两阶,如果你每次跨5阶最后剩4阶,如果你每次跨6阶,最后剩余5阶,只有当你每次跨7阶,才正好到头,这个楼梯到底有多少阶, 分析,因为每次跨7阶,才正好到头,说明楼梯的阶数是7的倍数 int main(){ ladder = 7; while(1){ if((ladder%2==1)&&(ladder%3==2)&&(ladder%5==4)&&(ladder%6==5)&&(ladder%7==0)){ printf("最少需要%d",ladder); break; } ladder+=7; } } 五家共井 现在有五家共用一口井,甲、乙、丙、丁、戌五家各有一条绳子汲水(下面用文字表示每一家的绳子):甲×2+乙=井深,乙×3+丙=井深,丙×4+丁=井深,丁×5+戌=井深,戌×6+甲=井深,求甲、乙、丙、丁、戌各家绳子的长度和井深。 分析 设井深为len,甲的绳长 len1,乙的 绳长 len2,丙 的绳长 len3,丁 的绳长 len4, 戌的绳长len5 由条件可得 len1*2+len2 = len len2*3+len3 = len len3*4+len4 = len len4*5+len5 = len

鸡兔同笼——算法详解

风格不统一 提交于 2020-01-07 14:52:54
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 借助李开复老师的话来聊聊算法的重要性:“算法是计算机科学领域最重要的基石之一,但却受到了国内一些程序员的冷落。许多学生看到一些公司在招聘时要求的编程语言五花八门就产生了一种误解,认为学计算机就是学各种编程语言,或者认为,学习最新的语言、技术、标准就是最好的铺路方法。其实大家都被这些公司误导了。编程语言虽然该学,但是学习计算机算法和理论更重要,因为计算机算法和理论更重要,因为计算机语言和开发平台日新月异,但万变不离其宗的是那些算法和理论,例如数据结构、算法、编译原理、计算机体系结构、关系型数据库原理等等。在“开复学生网”上,有位同学生动地把这些基础课程比拟为“内功”,把新的语言、技术、标准比拟为“外功”。整天赶时髦的人最后只懂得招式,没有功力,是不可能成为高手的。” 今天我们一起来看看经典的鸡兔同笼问题。 问题如下:数学中有个经典的“鸡兔同笼”问题,已知笼中的头共30个, 脚共90只,问鸡和兔各有多少只? 数学解题实现: 设鸡有 X 只,兔有 Y 只,根据题意得到两个二元一次方程组: X + Y =30 2*X+4*Y=90 然后解得X=15,Y=15。 下面编程实现: #include using namespace std; int main() { int head,foot; cout<<

算法——union-find算法

断了今生、忘了曾经 提交于 2020-01-07 13:07:28
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 问题 :问题的输入是一列整数对,其中每个整数都表示一个某种类型的对象,一对整数p q可以被理解为“p和q是相连的”。 当程序从输入中读取了整数对p q时,如果已知的所有整数对都不能说明p和q是相连的,那么则将这一对整数写入到输出中;如果已知数据可以说明p和q是相连的,那么程序应该忽略p q这对整数并继续处理输入中的下一对整数。我们将这个问题通俗地叫做 动态连通性 问题。 应用如下:输入的整数表示的可能是一个大型计算机网络中的计算机,而整数对则表示网络中的连接。这个程序能够判断我们是够需要在p和q之间架设一条新的连接才能进行通信,或是我们可以通过已有的连接在两者之间建立通信线路。 union-find算法的API public class UF UF (int N) 以整数标志(0到N-1)初始化N个触点 void union (int p,int q) 在p和q之间建立一条连接 int find (int p) p(0到N-1)所在分量的标识符 boolean connected (int p,int q) 如果p和q存在于同一个分量中则返回true int count() 连通分量的数量 我们将讨论三种不同的实现,他们均根据以触点为索引的id[]数组来确定两个触点是否存在于相同的连通分量中。 1. quick

面试常考的常用数据结构与算法【简】

↘锁芯ラ 提交于 2020-01-07 08:32:18
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 数据结构与算法,这个部分的内容其实是十分的庞大,要想都覆盖到不太容易。在校学习阶段我们可能需要对每种结构,每种算法都学习,但是找工作笔试或者面试的时候,要在很短的时间内考察一个人这方面的能力,把每种结构和算法都问一遍不太现实。所以,实际的情况是,企业一般考察一些看起来很基本的概念和算法,或者是一些变形,然后让你去实现。也许看起来简单,但是如果真让你在纸上或者是计算机上快速地完成一个算法,并且设计测试案例,最后跑起来,你就会发现会很难了。这就要求我们要熟悉,并牢固掌握常用的算法,特别是那些看起来貌似简单的算法,正是这些用起来很普遍的算法,才要求我们能很扎实的掌握,在实际工作中提高工作效率。遇到复杂的算法,通过分析和扎实的基本功,应该可以很快地进行开发。 闲话少说,下面进入正题。 一.数据结构部分 1. 数组和链表的区别 。(很简单,但是很常考,记得要回答全面) C++语言中可以用 数组 处理一组数据类型相同的数据,但 不允许动态定义数组的大小 ,即在使用数组之前必须确定数组的大小。而在实际应用中,用户使用数组之前有时无法准确确定数组的大小,只能将数组定义成足够大小,这样数组中有些空间可能不被使用,从而 造成内存空间的浪费 。 链表是一种常见的数据组织形式,它采用动态分配内存的形式实现 。需要时可以用

蚂蚁金服服务注册中心数据分片和同步方案详解 | SOFARegistry 解析

那年仲夏 提交于 2020-01-07 05:26:45
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> SOFAStack( S calable O pen F inancial A rchitecture Stack) 是蚂蚁金服自主研发的金融级分布式架构,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。 SOFARegistry 是蚂蚁金服开源的具有承载海量服务注册和订阅能力的、高可用的服务注册中心,在支付宝/蚂蚁金服的业务发展驱动下,近十年间已经演进至第五代。 本文为《剖析 | SOFARegistry 框架》第四篇, 本篇作者明不二 。《剖析 | SOFARegistry 框架》系列由 SOFA 团队和源码爱好者们出品,项目代号: SOFA:RegistryLab/ ,文末包含往期系列文章。 GitHub 地址: https://gitee.com/sofastack/sofa-registry 概述 在前面的章节中我们已经提到,SOFARegistry 与其他服务发现领域的产品相比,最大的不同点在于支持海量数据。本章即将讲述 SOFARegistry 在支撑海量数据上的一些特性。 本文将从如下几个方面进行讲解: DataServer 总体架构 :对 SOFARegistry 中支持海量数据的总体架构做一个简述,讲解数据分片和同步方案中所涉及到的关键技术点;

机器学习算法—KNN算法原理

人走茶凉 提交于 2020-01-07 02:49:50
机器学习算法—KNN算法原理 概述: KNN算法一般也会经常被称为K邻近算法,其核心思想是根据训练集中的样本分类计算测试集中样本与训练集中所有样本的距离,根据所设定的K值选取前K个测试样本与训练样本最近的结果,结果中大多数训练样本所处在的类别即是本测试样本的类别。因训练样本的分类结果为已知因此KNN算法属于有监督学习算法。 算法原理: 1、以下图样本散点图展示训练集的整体分布情况 从散点图中可以发现训练集的数据分类数量为3个类别,分别为蓝色类别、红色类别和黄色类别,训练样本总数为15个。 2、导入第一个测试样本 3、需要根据已知的训练样本分类结果判断测试样本的类别,因此计算测试样本与所有训练样本的距离 因训练样本数量为15,所以计算完成的距离参数为15个。 4、K值是KNN算法中唯一需要设定的参数,假定K值为3则在15个距离参数中选择最近的3个 统计3个距离中大部分训练样本所处的分类即为本测试样本的分类,本次分类中距离最近的3个训练样本有2个属于红色类别,因此本测试样本被分类为红色 5、对下一个测试样本以相同方式进行距离计算和分类 注意事项: 1、K的取值尽量为奇数以确保距离计算结果必定会有一个K个距离中包括较多的类别,比如例子中取3,则3个中有2个训练样本为红色类别以此判断测试样本属于红色类别。如K取4产生下图中的情况 4个距离参数中,2个训练样本为红色类别

算法笔记 26040 Problem B 习题6-5 数组元素逆置

孤街浪徒 提交于 2020-01-07 02:03:35
问题 B: 习题6-5 数组元素逆置 时间限制: 1 Sec 内存限制: 12 MB 题目描述 将一个长度为10的整型数组中的值按逆序重新存放。 如:原来的顺序为1,2,3,4,5,6,7,8,9,0,要求改为0,9,8,7,6,5,4,3,2,1 输入 从键盘上输入以空格分隔的10个整数。 输出 按相反的顺序输出这10个数,每个数占一行。 样例输入 1 2 3 4 5 6 7 8 9 0 样例输出 0 9 8 7 6 5 4 3 2 1 # include <stdio.h> int main ( ) { int a [ 10 ] ; int n , i , t ; for ( i = 0 ; i < 10 ; i ++ ) { scanf ( "%d " , & a [ i ] ) ; } for ( n = 0 ; n < 9 ; n ++ ) { for ( i = 9 ; i > n ; i -- ) { t = a [ i ] ; a [ i ] = a [ i - 1 ] ; a [ i - 1 ] = t ; } } for ( i = 0 ; i < 10 ; i ++ ) { printf ( "%d\n" , a [ i ] ) ; } return 0 ; } 来源: CSDN 作者: ZOE_ZHU 链接: https://blog.csdn.net/qq