|NO.Z.00044|——————————|BigDataEnd|——|Hadoop&ElasticSearch.V44|——|ELK.v44|原理剖析|数据结构.V2|
一、调表实现:编程实现
### --- 调表实现:编程实现
package com.yanqi.es;
import java.util.Comparator;
//存储kv类型数据
public class SkipList<K, V> {
//头节点
private Node<K, V> first;
//最高层数
private static final int MAX_LEVEL = 10;
//当前跳表有效层数
private int realLeve;
//新节点随机的层数的概率
private static final double f = 0.25;
//容量
int size;
//skiplist中key必须具有可比较性
private Comparator<K> comparator;
//构造器
public SkipList(Comparator<K> comparator) {
this.first = new Node(null, null, MAX_LEVEL);
this.comparator = comparator;
}
public SkipList() {
this(null);//不传比较器,就是默认你的key一定实现了java的compareble接口
}
//比较方法
int compare(K k1, K k2) {
int cmp = comparator == null ? ((Comparable) k1).compareTo(k2) :
comparator.compare(k1, k2);
return cmp;
}
int getSize() {
return 0;
}
//是否为空
boolean isEmpty() {
return size == 0;
}
//校验key
public void checkKeyIsNull(K key) {
if (key == null) {
throw new IllegalArgumentException("key should not be null...");
}
}
//增删查
V get(K key) {
/**
* - 从顶层链表的首元素开始,从左往右搜索,直至找到一个大于或等于目标的元素,或者到达当前层链表的尾部
* - 如果该元素等于目标元素,则表明该元素已被找到
* - 如果该元素大于目标元素或已到达链表的尾部,则退回到当前层的前一个元素,然后转入下一层进行搜索
*/
checkKeyIsNull(key);
//获取头节点
Node<K, V> node = first;
for (int i = realLeve - 1; i >= 0; i--) {
//查找的key大于遇到的节点的key一直向右
int cmp = -1;
while (node.nexts[i] != null && (cmp = compare(key, node.nexts[i].key)) > 0) {
//一直向右
node = node.nexts[i];
}
//说明查找的key小于等于node.nexts[i].key
if (cmp == 0) {
//找到了节点
return node.nexts[i].value;
}
}
//跳表中不存在这个key
return null;
}
//根据key查找value
V put(K key, V value) { checkKeyIsNull(key);
//确定新节点的位置与get过程类似
Node<K, V> node = first;
//初始化一个装新节点前面节点的数组,数组长度:有效层数
final Node<K, V>[] prevNodes = new Node[realLeve];
for (int i = realLeve - 1; i >= 0; i--) {
//查找的key大于遇到的节点的key一直向右
int cmp = -1;
while (node.nexts[i] != null && (cmp = compare(key, node.nexts[i].key)) > 0) {
//一直向右
node = node.nexts[i];
}
//说明查找的key小于等于node.nexts[i].key
if (cmp == 0) {//更新
// 找到了节点
// 要覆盖的节点是node.nexts[i]
final V oldValue = node.nexts[i].value;
node.nexts[i].value = value;
return oldValue;
}
//这里就是向下一层的动作
prevNodes[i] = node;
}
//确定插入的位置,就是上述循环之后的node节点,就是在node节点之后插入新节点;
// 获取到新节点的层数
int newLeve = getNewNodeLeve();
Node<K, V> newNode = new Node<>(key, value, newLeve);//新节点的层数如何确定呢?随机
// 新节点前面的节点的特征:都有向下一层的动作
for (int i = 0; i < newLeve; i++) {
//如果新节点层数大于realLevel
if (i >= realLeve) {
first.nexts[i] = newNode;
} else {
newNode.nexts[i] = prevNodes[i].nexts[i];
prevNodes[i].nexts[i] = newNode;
}
}
//容量增加
size++;
//跳表有效层数更新
realLeve = Math.max(realLeve, newLeve);
return null;
}
private int getNewNodeLeve() {
int level = 1;
if (Math.random() < f && level < MAX_LEVEL) {
level++;
}
return level;
}
V remove(K key) { checkKeyIsNull(key);
//确定删除节点的位置
Node<K, V> node = first;
//初始化一个装目标节点前面节点的数组,数组长度:有效层数
final Node<K, V>[] prevNodes = new Node[realLeve];
boolean flag = false;
for (int i = realLeve - 1; i >= 0; i--) {
//查找的key大于遇到的节点的key一直向右
int cmp = -1;
while (node.nexts[i] != null && (cmp = compare(key, node.nexts[i].key)) > 0) {
//一直向右
node = node.nexts[i];
}
if (cmp == 0) {
//找到了删除的key
flag = true;
}
//这里就是向下一层的动作
prevNodes[i] = node;
}
//判断flag标识
if (!flag) {
//没有找到目标元素
return null;
}
//找到了删除的元素,执行删除动作
// 确定要删除的节点
Node<K, V> deleteNode = node.nexts[0];
//与添加类似
for (int i = 0; i < deleteNode.nexts.length; i++) {
prevNodes[i].nexts[i] = deleteNode.nexts[i];
}
//关于跳表的有效层数进行更新,删除的目标节点有可能是跳表中最高层,需要修改跳表的有效层数
int finalLeve = realLeve;
while (--finalLeve >= 0 && first.nexts[finalLeve] == null) {
//有效层数要减1
realLeve = finalLeve;
}
return deleteNode.value;
}
private static class Node<K, V> {
K key;
V value;
Node<K, V>[] nexts; //向后多个节点的引用
//构造器
public Node(K key, V value, int level) {
this.key = key;
this.value = value;
this.nexts = new Node[level];
}
@Override
public String toString() {
return key + ":" + value + "_" + nexts.length;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("一共" + realLeve + "层").append("\n");
for (int i = realLeve - 1; i >= 0; i--) {
Node<K, V> node = first;
while (node.nexts[i] != null) {
sb.append(node.nexts[i]);
sb.append(" ");
node = node.nexts[i];
}
sb.append("\n");
}
return sb.toString();
}
}
### --- 编程实现测试类
package com.yanqi.es;
public class SkipListTest {
public static void main(String[] args) {
final SkipList<Integer, String> list = new SkipList<>();
list.put(1,"aaa" );
list.put(2,"bbb" );
// System.out.println(list);
//
System.out.println(list.get(1));
list.remove(1);
System.out.println(list);
}
}
### --- 编译打印
D:\JAVA\jdk1.8.0_231\bin\java.exe "-javaagent:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=58581:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\JAVA\jdk1.8.0_231\jre\lib\charsets.jar;D:\JAVA\jdk1.8.0_231\jre\lib\deploy.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\access-bridge-64.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\cldrdata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\dnsns.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jaccess.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jfxrt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\localedata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\nashorn.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunec.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunjce_provider.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunmscapi.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunpkcs11.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\zipfs.jar;D:\JAVA\jdk1.8.0_231\jre\lib\javaws.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jce.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfr.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfxswt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jsse.jar;D:\JAVA\jdk1.8.0_231\jre\lib\management-agent.jar;D:\JAVA\jdk1.8.0_231\jre\lib\plugin.jar;D:\JAVA\jdk1.8.0_231\jre\lib\resources.jar;D:\JAVA\jdk1.8.0_231\jre\lib\rt.jar;E:\NO.Z.80000.Hadoop.project\elasticsearch\target\classes;C:\Users\Administrator\.m2\repository\org\elasticsearch\client\elasticsearch-rest-high-level-client\7.9.0\elasticsearch-rest-high-level-client-7.9.0.jar;C:\Users\Administrator\.m2\repository\org\elasticsearch\client\elasticsearch-rest-client\7.9.0\elasticsearch-rest-client-7.9.0.jar;C:\Users\Administrator\.m2\repository\org\apache\httpcomponents\httpclient\4.5.10\httpclient-4.5.10.jar;C:\Users\Administrator\.m2\repository\org\apache\httpcomponents\httpcore\4.4.12\httpcore-4.4.12.jar;C:\Users\Administrator\.m2\repository\org\apache\httpcomponents\httpasyncclient\4.1.4\httpasyncclient-4.1.4.jar;C:\Users\Administrator\.m2\repository\org\apache\httpcomponents\httpcore-nio\4.4.12\httpcore-nio-4.4.12.jar;C:\Users\Administrator\.m2\repository\commons-codec\commons-codec\1.11\commons-codec-1.11.jar;C:\Users\Administrator\.m2\repository\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;C:\Users\Administrator\.m2\repository\org\elasticsearch\plugin\mapper-extras-client\7.9.0\mapper-extras-client-7.9.0.jar;C:\Users\Administrator\.m2\repository\org\elasticsearch\plugin\parent-join-client\7.9.0\parent-join-client-7.9.0.jar;C:\Users\Administrator\.m2\repository\org\elasticsearch\plugin\aggs-matrix-stats-client\7.9.0\aggs-matrix-stats-client-7.9.0.jar;C:\Users\Administrator\.m2\repository\org\elasticsearch\plugin\rank-eval-client\7.9.0\rank-eval-client-7.9.0.jar;C:\Users\Administrator\.m2\repository\org\elasticsearch\plugin\lang-mustache-client\7.9.0\lang-mustache-client-7.9.0.jar;C:\Users\Administrator\.m2\repository\com\github\spullara\mustache\java\compiler\0.9.6\compiler-0.9.6.jar;C:\Users\Administrator\.m2\repository\org\elasticsearch\elasticsearch\7.9.0\elasticsearch-7.9.0.jar;C:\Users\Administrator\.m2\repository\org\elasticsearch\elasticsearch-core\7.9.0\elasticsearch-core-7.9.0.jar;C:\Users\Administrator\.m2\repository\org\elasticsearch\elasticsearch-secure-sm\7.9.0\elasticsearch-secure-sm-7.9.0.jar;C:\Users\Administrator\.m2\repository\org\elasticsearch\elasticsearch-x-content\7.9.0\elasticsearch-x-content-7.9.0.jar;C:\Users\Administrator\.m2\repository\org\yaml\snakeyaml\1.26\snakeyaml-1.26.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.10.4\jackson-core-2.10.4.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\dataformat\jackson-dataformat-smile\2.10.4\jackson-dataformat-smile-2.10.4.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\dataformat\jackson-dataformat-yaml\2.10.4\jackson-dataformat-yaml-2.10.4.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\dataformat\jackson-dataformat-cbor\2.10.4\jackson-dataformat-cbor-2.10.4.jar;C:\Users\Administrator\.m2\repository\org\elasticsearch\elasticsearch-geo\7.9.0\elasticsearch-geo-7.9.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-core\8.6.0\lucene-core-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-analyzers-common\8.6.0\lucene-analyzers-common-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-backward-codecs\8.6.0\lucene-backward-codecs-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-grouping\8.6.0\lucene-grouping-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-highlighter\8.6.0\lucene-highlighter-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-join\8.6.0\lucene-join-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-memory\8.6.0\lucene-memory-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-misc\8.6.0\lucene-misc-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-queries\8.6.0\lucene-queries-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-queryparser\8.6.0\lucene-queryparser-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-sandbox\8.6.0\lucene-sandbox-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-spatial-extras\8.6.0\lucene-spatial-extras-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-spatial3d\8.6.0\lucene-spatial3d-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\apache\lucene\lucene-suggest\8.6.0\lucene-suggest-8.6.0.jar;C:\Users\Administrator\.m2\repository\org\elasticsearch\elasticsearch-cli\7.9.0\elasticsearch-cli-7.9.0.jar;C:\Users\Administrator\.m2\repository\net\sf\jopt-simple\jopt-simple\5.0.2\jopt-simple-5.0.2.jar;C:\Users\Administrator\.m2\repository\com\carrotsearch\hppc\0.8.1\hppc-0.8.1.jar;C:\Users\Administrator\.m2\repository\joda-time\joda-time\2.10.4\joda-time-2.10.4.jar;C:\Users\Administrator\.m2\repository\com\tdunning\t-digest\3.2\t-digest-3.2.jar;C:\Users\Administrator\.m2\repository\org\hdrhistogram\HdrHistogram\2.1.9\HdrHistogram-2.1.9.jar;C:\Users\Administrator\.m2\repository\org\elasticsearch\jna\5.5.0\jna-5.5.0.jar;C:\Users\Administrator\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\Administrator\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4j-core\2.5\log4j-core-2.5.jar;C:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4j-api\2.5\log4j-api-2.5.jar com.yanqi.es.SkipListTest
aaa
一共1层
2:bbb_1
Process finished with exit code 0
Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
——W.S.Landor
分类:
bdv025-elk
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通