package com.company.structure.skiplist;
import java.util.List;
/**
* @author zhangjw
* @date 2021/2/20 0:42
*/
public class ZSkipListNode {
private String value;
private double score;
private ZSkipListNode backward;
private List<ZSkipListLevel> level;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public ZSkipListNode getBackward() {
return backward;
}
public void setBackward(ZSkipListNode backward) {
this.backward = backward;
}
public List<ZSkipListLevel> getLevel() {
return level;
}
public void setLevel(List<ZSkipListLevel> level) {
this.level = level;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ZSkipListNode)) {
// instanceof 已经处理了obj = null的情况
return false;
}
ZSkipListNode stuObj = (ZSkipListNode) obj;
// 地址相等
if (this == stuObj) {
return true;
}
if (stuObj.value.equals(this.value) && stuObj.score == this.score) {
return true;
} else {
return false;
}
}
@Override
public int hashCode() {
int result =String.valueOf(this.score).hashCode();
if (value!=null){
result = 17 * result + this.value.hashCode();
}else if (value == null){
result = 17 * result + "zsl".hashCode();
}
return result;
}
}
package com.company.structure.skiplist;
/**
* @author zhangjw
* @date 2021/2/20 0:47
*/
public class ZSkipListLevel {
/**
* 前向指针
*/
private ZSkipListNode forward;
/**
* 跨度
*/
private int span;
public ZSkipListNode getForward() {
return forward;
}
public void setForward(ZSkipListNode forward) {
this.forward = forward;
}
public int getSpan() {
return span;
}
public void setSpan(int span) {
this.span = span;
}
}
package com.company.structure.skiplist;
import com.sun.deploy.util.StringUtils;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhangjw
* @date 2021/2/20 0:50
*/
public class ZSkipList {
private static final SecureRandom RANDOM = new SecureRandom();
private static double ZSKIPLIST_P = 0.25;
/**
* 表头指针
*/
private ZSkipListNode header;
/**
* 表尾指针
*/
private ZSkipListNode tail;
/**
* 表中节点的数量
*/
private int length;
/**
* 表中最大的节点的层数
*/
private int level;
public ZSkipListNode getHeader() {
return header;
}
public void setHeader(ZSkipListNode header) {
this.header = header;
}
public ZSkipListNode getTail() {
return tail;
}
public void setTail(ZSkipListNode tail) {
this.tail = tail;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
/**
* 创建链表节点
*
* @param level
* @param score
* @param value
* @return
*/
public static ZSkipListNode zslCreateNode(int level, double score, String value) {
ZSkipListNode znode = new ZSkipListNode();
List<ZSkipListLevel> levels = new ArrayList<>();
for (int i = 0; i < level; i++) {
levels.add(new ZSkipListLevel());
}
znode.setScore(score);
znode.setValue(value);
znode.setLevel(levels);
return znode;
}
public ZSkipList() {
zlsCreate();
}
/**
* 创建链表
*
* @return
*/
private ZSkipList zlsCreate() {
this.setLevel(1);
this.setLength(0);
ZSkipListNode header = zslCreateNode(ZEnum.ZSKIPLIST_MAXLEVEL.getVal(), 0, null);
this.setHeader(header);
for (int j = 0; j < ZEnum.ZSKIPLIST_MAXLEVEL.getVal(); j++) {
header.getLevel().get(j).setForward(null);
header.getLevel().get(j).setSpan(1);
}
header.setBackward(null);
this.setTail(null);
return this;
}
/**
* 跳表插入方法
*
* @param zSkipList
* @param score
* @param value
* @return
*/
public ZSkipListNode zslInsert(ZSkipList zSkipList, double score, String value) {
ZSkipListNode update[] = new ZSkipListNode[ZEnum.ZSKIPLIST_MAXLEVEL.getVal()];
int rank[] = new int[ZEnum.ZSKIPLIST_MAXLEVEL.getVal()];
// 在各个层查找节点的插入位置
int i = 0, level = 0;
ZSkipListNode x = zSkipList.getHeader();
for (i = zSkipList.getLevel() - 1; i >= 0; i--) {
/* 一层一层的找,这是第i层, 这个rank[]值得玩味和思考,
*多插入几个节点。在纸上多演练几遍就理解了
*/
rank[i] = i == zSkipList.getLevel() - 1 ? 0 : rank[i + 1];
while (x.getLevel().get(i).getForward() != null
&& (x.getLevel().get(i).getForward().getScore() < score ||
x.getLevel().get(i).getForward().getValue().compareTo(value) < 0)) {
// 记录沿途跨越了多少个节点
rank[i] += x.getLevel().get(i).getSpan();
x = x.getLevel().get(i).getForward();
}
// 记录将要和新节点相连接的节点
update[i] = x;
}
level = randomLevel();
/* 如果新节点的层数比表中其他节点的层数都要大
* 那么初始化表头节点中未使用的层,并将它们记录到 update 数组中
* 将来也指向新节点
*/
if (level > zSkipList.getLevel()) {
for (i = zSkipList.getLevel(); i < level; i++) {
// 初始化未使用层
rank[i] = 0;
update[i] = zSkipList.getHeader();
update[i].getLevel().get(i).setSpan(zSkipList.getLength());
}
// 更新表的最大层数
zSkipList.setLevel(level);
}
// 创建新节点
x = zslCreateNode(level, score, value);
for (i = 0; i < level; i++) {
// 设置新节点的 forward 指针
x.getLevel().get(i).setForward(update[i].getLevel().get(i).getForward());
// 将沿途记录的各个节点的 forward 指针指向新节点
update[i].getLevel().get(i).setForward(x);
// 计算新节点跨越的节点数量
x.getLevel().get(i).setSpan(update[i].getLevel().get(i).getSpan() - (rank[0] - rank[i]));
/*
更新新节点插入之后,沿途节点的 span 值
其中的 +1 计算的是新节
*
*/
update[i].getLevel().get(i).setSpan(rank[0] - rank[i] + 1);
}
// 未接触的节点的 span 值也需要增一,这些节点直接从表头指向新节点
for (i = level; i < zSkipList.getLevel(); i++) {
int oldSpan = update[i].getLevel().get(i).getSpan();
update[i].getLevel().get(i).setSpan(oldSpan + 1);
}
// 设置新节点的后退指针
x.setBackward(update[0] == zSkipList.getHeader() ? null : update[0]);
if (x.getLevel().get(0).getForward() != null) {
// 新节点的前置节点的后置节点就是x
x.getLevel().get(0).getForward().setBackward(x);
} else {
zSkipList.setTail(x);
}
// 节点数加一
zSkipList.setLength(zSkipList.getLength() + 1);
return x;
}
/**
* 随机生成一个层数,这个方法和源码不完全一样
* 可以看下源码
*
* @return
*/
private int randomLevel() {
return RANDOM.nextInt(ZEnum.ZSKIPLIST_MAXLEVEL.getVal()-1);
/* while ((RANDOM.nextInt() & 655535) < (ZSKIPLIST_P * 65535)) {
level++;
}
System.out.println("得到的level 是:" +level);
return level < ZEnum.ZSKIPLIST_MAXLEVEL.getVal() ? level : ZEnum.ZSKIPLIST_MAXLEVEL.getVal();*/
}
public int zslGetRank(ZSkipList zSkipList, double score, String value) {
int rank = 0;
ZSkipListNode x;
int i;
// 遍历整个跳表
x = zSkipList.getHeader();
for (i = zSkipList.getLevel() - 1; i >= 0; i--) {
while (x.getLevel().get(i).getForward() != null && (
x.getLevel().get(i).getForward().getScore() < score
|| (x.getLevel().get(i).getForward().getScore() == score &&
x.getLevel().get(i).getForward().getValue().compareTo(value) < 0))) {
// 累积跨越的节点的数量
rank += x.getLevel().get(i).getSpan();
// 沿着前进指针遍历跳跃表
x = x.getLevel().get(i).getForward();
if (x.getValue() != null && x.getValue().equals(value)) {
return rank;
}
}
}
// 没有找到
return 0;
}
public int zslDelete(ZSkipList zSkipList, double score, String value) {
ZSkipListNode update[] = new ZSkipListNode[ZEnum.ZSKIPLIST_MAXLEVEL.getVal()];
ZSkipListNode x;
int i;
x = zSkipList.getHeader();
for (i = zSkipList.getLevel() - 1; i >= 0; i--) {
// 寻找x
while (x.getLevel().get(i).getForward() != null && (
x.getLevel().get(i).getForward().getScore() < score
|| (x.getLevel().get(i).getForward().getScore() == score &&
x.getLevel().get(i).getForward().getValue().compareTo(value) < 0))) {
x = x.getLevel().get(i).getForward();
}
update[i] = x;
}
x = x.getLevel().get(0).getForward();
if (x != null && x.getScore() == score && x.getValue().compareTo(value) == 0) {
zslDeleteNode(zSkipList, x, update);
return 1;
} else {
return 0;
}
}
public void zslDeleteNode(ZSkipList zSkipList, ZSkipListNode x, ZSkipListNode update[]) {
int i;
for (i = 0; i < zSkipList.getLevel(); i++) {
if (x.getLevel().get(i).getForward() == x) {
update[i].getLevel().get(i).setSpan(update[i].getLevel().get(i).getSpan() + x.getLevel().get(i).getSpan() - 1);
update[i].getLevel().get(i).setForward(x.getLevel().get(i).getForward());
}
}
// 更新后置节点
if (x.getLevel().get(0).getForward() != null) {
x.getLevel().get(0).getForward().setBackward(x.getBackward());
} else {
zSkipList.setTail(x.getBackward());
}
// 更新跳跃表的最大层数,只在要删除的节点在最高的层数时才更新
while (zSkipList.getLevel() > 1 && zSkipList.getHeader().getLevel().get(zSkipList.getLevel() - 1) == null) {
zSkipList.setLevel(zSkipList.getLevel() - 1);
}
// 更新跳跃表的节点的总个数
zSkipList.setLevel(zSkipList.getLength() - 1);
}
}
package com.company.structure.skiplist;
/**
* @author zhangjw
* @date 2021/3/2 12:26
*/
public class Zrangespec {
private double min;
private double max;
/**
* 指示最小值和最大值是否包含在范围之内
*/
private int minex;
private int maxex;
public double getMin() {
return min;
}
public void setMin(double min) {
this.min = min;
}
public double getMax() {
return max;
}
public void setMax(double max) {
this.max = max;
}
public int getMinex() {
return minex;
}
public void setMinex(int minex) {
this.minex = minex;
}
public int getMaxex() {
return maxex;
}
public void setMaxex(int maxex) {
this.maxex = maxex;
}
}
package com.company.structure.skiplist;
/**
* @author zhangjw
* @date 2021/2/23 2:11
*/
public enum ZEnum {
ZSKIPLIST_MAXLEVEL(32);
private int val;
ZEnum(int val) {
this.val = val;
}
public int getVal() {
return val;
}
}
package com.company.structure.skiplist;
/**
* @author zhangjw
* @date 2021/3/6 18:10
*/
public class OpTest {
public static void main(String[] args) {
// 建立一个链表
ZSkipList zsl = new ZSkipList();
System.out.println("链表有 " + zsl.getLevel() + "层");
System.out.println("头节点是 "+ zsl.getHeader());
System.out.println("==============================================");
// 插入一个节点
zsl.zslInsert(zsl, 10.0, "a");
zsl.zslInsert(zsl, 11.0, "b");
System.out.println("表中有 " + zsl.getLength() +"个节点");
System.out.println("链表有 " + zsl.getLevel() + "层");
// 遍历链表各层节点,并打印相关属性
for (int i=0; i< zsl.getLevel(); i++){
System.out.println("第 " + i +"层开始打印");
ZSkipListNode header = zsl.getHeader();
while (header != null){
System.out.print("{value:"+header.getValue()+",");
System.out.print("span:"+header.getLevel().get(i).getSpan()+"}");
header = header.getLevel().get(i).getForward();
System.out.print("-->");
}
System.out.println();
System.out.println("第 "+i +"层打印完毕");
}
}
}
redis源码跳表
最新推荐文章于 2024-04-24 20:45:53 发布