跳表的java实现,转载自网络,仅供自己学习使用
文档结构:
1、代码结构
2、代码实现
1、代码结构
节点类:
String key 键值 对跳跃表的操作都是根据键值进行的
Int value 实际值
Node up,down,left,right; 每个节点都有四个方向
String tou;
String wei; 每层链表的头和尾节点
跳跃表类:
Head 头节点
Tail 尾结点
H 层数
Size 元素个数
Random 随机数,用来确定需不需要增加层数 即:掷硬币
findF () 按从小到大的顺序找到应该插入的位置 插入排序法
Add () 添加节点函数,在最底层插入结点后,进行掷硬币来确定是否需要曾增加层数,直到掷硬币不能增加层数为止,增加层数的同事需要把增加之后的节点进行连接。
Find() 根据跳跃表进行查找并打印路线。查找从最上层开始然后找到被查找节点的前个节点小于被查找节点,然后被查找节点的后一个节点大于其被查找节点,则从被查找节点的前一个节点向下走down,然后继续向右查找,直到找到为止。
2、代码实现
- package 跳跃表;
- import java.util.*;
- public class SkipList {
- public Node head; //头节点
- public Node tail; //尾结点
- public int h; //层数
- public int size; //元素个数
- public Random rand; //每次的随机数用来确定需不需要增加层数
- public SkipList(){
- Node p1 = new Node(Node.tou,0);
- Node p2 = new Node(Node.wei, 0);
- head=p1;
- tail=p2;
- head.setRight(tail);
- tail.setLeft(head);
- h=0;
- size=0;
- rand = new Random();
- }
- public boolean isEmpty(){
- if(size==0){
- return true;
- }
- return false;
- }
- //找到需要插入位置的前一个节点
- public Node findF(String k){
- Node temp;
- temp=head;
- while(true){
- while(temp.getRight().key!=Node.wei&&temp.getRight().key.compareTo(k)<=0){
- /*
- * 当链表最底层不为空的时候,从当前层向尾部方向开始查找,直到查找temp.getRight的下一个值大于 当前k的值为止,此时temp小于或等于当前k的值
- * 要插入的位置即为temp之后的位置了
- */
- temp=temp.getRight();
- }
- if(temp.getDown()!=null){
- temp=temp.getDown();
- }else{
- break;
- }
- }
- return temp; //找到节点并返回
- }
- public int add(String k, int v){
- Node temp, temp1;
- temp=findF(k);
- int i; //当前层数
- if(k.equals(temp.getKey())){
- System.out.println("对象属性完全相同无法添加!");
- int a=temp.value;
- temp.value=v;
- return a;
- }
- temp1=new Node(k,v);
- temp1.setLeft(temp);
- temp1.setRight(temp.getRight());
- temp.getRight().setLeft(temp1);
- temp.setRight(temp1);
- i=0;
- while(rand.nextDouble()<0.5){ //进行随机,是否需要 在上层添加
- if(i>=h){ //若当前层数超出了高度,则需要另建一层
- Node p1 ,p2 ;
- h=h+1;
- p1=new Node(Node.tou,0);
- p2=new Node(Node.wei,0);
- p1.setRight(p2);
- p1.setDown(head);
- p2.setLeft(p1);
- p2.setDown(tail);
- head.setUp(p1);
- tail.setUp(p2);
- head=p1;
- tail=p2;
- }
- while(temp.getUp() == null){
- temp=temp.getLeft();
- }
- temp=temp.getUp();
- Node node=new Node(k,v);
- node.setLeft(temp);
- node.setRight(temp.getRight());
- node.setDown(temp1);
- temp.getRight().setLeft(node);
- temp.setRight(node);
- temp1.setUp(node);
- temp1=node;
- i=i+1;
- }
- size=size+1;
- return 0;
- }
- //节点查找
- public Node find(String k){
- Node temp=head;
- Node node;
- node=temp;
- System.out.println("查找路线"); //用于测试
- while(temp!=null){
- while(node.getRight().key!=Node.wei&&node.getRight().getKey().compareTo(k)<=0){//&&node.getRight().getValue()!=v
- node=node.getRight();
- System.out.print("--->"+node.getKey());
- }
- if(node.getDown()!=null){
- node=node.getDown();
- System.out.print("--->"+node.getKey());
- }else{
- if(node.key.equals(k)){//&&node.getRight().value==v
- //node.setValue(111111111); //修改
- System.out.println("--->"+node.getKey());
- System.out.print("--->"+node.getValue());
- return node;
- }
- return null;
- }
- }
- return null;
- }
- //节点删除
- public void delNode(String k){ //调用查找函数,删除最底层的某个节点,并把其节点的左右相连,和链表操作一样,只是其上方若有则都需要调整
- Node temp=find(k);
- while(temp!=null){
- temp.getLeft().setRight(temp.getRight());
- temp.getRight().setLeft(temp.getLeft());
- temp=temp.getUp();
- }
- }
- public void print(){
- Node node;
- Node node1=head;
- while(node1!=null){
- int k=0;
- node=node1;
- while(node!=null){
- System.out.print(node.getKey()+"\t");
- k++;
- node=node.getRight();
- }
- System.out.print("\t");
- System.out.print("("+k+")");
- //System.out.print(node.getKey());
- System.out.println();
- //node=node1.getDown();
- node1=node1.getDown();
- }
- }
- }
- class Node{
- public String key;
- public int value;
- public Node up, down,left , right;
- public static String tou=new String("--头--");
- public static String wei=new String("--尾--");
- public Node(String k, int v){
- this.key=k;
- this.value=v;
- up=down=left=right=null;
- }
- public void setUp(Node up){
- this.up=up;
- }
- public Node getUp(){
- return up;
- }
- public void setDown(Node down){
- this.down=down;
- }
- public Node getDown(){
- return down;
- }
- public void setLeft(Node left){
- this.left=left;
- }
- public Node getLeft(){
- return left;
- }
- public void setRight(Node right){
- this.right=right;
- }
- public Node getRight(){
- return right;
- }
- public void setKey(String k){
- this.key=k;
- }
- public String getKey(){
- return key;
- }
- public void setValue(int v){
- this.value=v;
- }
- public int getValue(){
- return value;
- }
- }
- package 跳跃表;
- public class Test {
- public static void main(String[] args){
- SkipList s = new SkipList();
- // s.add("AAA", 122);
- int i=0;
- for(;i<30;i++){ //随机数字进行测试
- s.add(String.valueOf(i), i);
- }
- s.print();
- System.out.println("\n\n----------\n\n\n");
- if(s.find("22")!=null){ //查找
- System.out.println("\nOK");
- }else{//找不到
- System.out.println("\nfalse");
- }
- s.delNode("0"); //删除
- s.print();
- }
- }
跳表的java实现,转载自网络,仅供自己学习使用的更多相关文章
- SQLyog试用到期的解决方法(仅供个人学习使用,禁止转载或用于商业盈利)
作者:EzrealYi 本章链接:https://www.cnblogs.com/ezrealyi/p/12434105.html win+r->输入regedit->进入注册表 在计算机 ...
- Java队列工具类(程序仅供练习)
public class QueueUtils<T> { public int defaultSize; public Object[] data; public int front = ...
- MySql提示:The server quit without updating PID file(…)失败之解决办法(来源网络仅供参考)
1.可能是/usr/local/mysql/data/rekfan.pid文件没有写的权限 解决方法 :给予权限,执行 “chown -R mysql:mysql /var/data” “chmod ...
- [转载] 跳表SkipList
原文: http://www.cnblogs.com/xuqiang/archive/2011/05/22/2053516.html leveldb中memtable的思想本质上是一个skiplist ...
- JAVA SkipList 跳表 的原理和使用例子
跳跃表是一种随机化数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作需要O(log n)平均时间),并且对并发算法友好. 关于跳跃表的具体介绍可以参考MIT的公开课:跳跃表 跳跃表的应 ...
- skiplist(跳表)的原理及JAVA实现
前记 最近在看Redis,之间就尝试用sortedSet用在实现排行榜的项目,那么sortedSet底层是什么结构呢? "Redis sorted set的内部使用HashMap和跳跃表(S ...
- java面试记录一:跳表、判断二叉树相同、冒泡排序、cookie和session的区别、设计模式(单例、工厂、模板方法、原型、代理、策略)、抽象类与接口的区别
1.什么是跳表? 跳表实际上就是多层链表 跳表可用在让链表的元素查询接近线性时间 代码结构及java实现参考博客园随笔 2.判断两棵二叉树是否相同?(结构相同,内容相同) 思路:(1)先定义树节点Tr ...
- 自己动手实现java数据结构(九) 跳表
1. 跳表介绍 在之前关于数据结构的博客中已经介绍过两种最基础的数据结构:基于连续内存空间的向量(线性表)和基于链式节点结构的链表. 有序的向量可以通过二分查找以logn对数复杂度完成随机查找,但由于 ...
- 跳表(SkipList)设计与实现(Java)
微信搜一搜「bigsai」关注这个有趣的程序员 文章已收录在 我的Github bigsai-algorithm 欢迎star 前言 跳表是面试常问的一种数据结构,它在很多中间件和语言中得到应用,我们 ...
随机推荐
- [Contract] Solidity 变量类型的默认值
变量的默认值一般都代表 “零值”. 比如 bool 就是 false,uint.int 就是 0,string 就是空字符串. 其它组合的参考 Solidity 判断 mapping 值的存在 Ref ...
- EF--EntityState相互转换
EF对数据做什么样的操作,是根据EF的上下文实体状态决定,实体状态有以下5种状态,下面我们就分别看下这5种状态 数据准备,我们看到学生表里有20000名学生记录,最后1位学生的学生编号为0000020 ...
- PS切图工具
缓存设置: 编辑-首选项-暂存盘 改完除了C盘之外的其他盘 单位设置: 编辑-首选项-单位与标尺 将单位修改成像素 PS预设: 工具 (窗口-工具) 标尺 (视图-标尺) 图层 (窗口-图层 ...
- postgresql 文件布局
我们知道linux中一个思想:一切皆文件,那么在我们安装完postgresql数据库后,她长什么样呢?本文带着你一起揭开她的面纱,看看postgresql的文件布局. 说明:由于安装测试的版本是10. ...
- 如何获取 iOS APP 的 scheme URL ?
获取IPA文件 拷贝到桌面上 后缀名由 .ipa 改为 .zip 解压之后进入,进入名为Payload的目录 右键点击里面的跟App同名的文件,选择'显示包内容' 用文本编辑器打开当前文件夹下的inf ...
- vim 进化 编码问题
" 解决菜单乱码 source $VIMRUNTIME/delmenu.vim source $VIMRUNTIME/menu.vim " 防止文件显示乱码 set fileenc ...
- Notes writer Pro
Notes writer Pro pen钢笔和Pencil铅笔发现没啥区别 笔记软件使用说明书: https://www.lanzous.com/i777i3c
- python—lambda函数,三个常用的高阶函数
"""lambda 参数列表 : 返回值lambda 参数形式: 1.无参数:lambda:100 2.一个参数:lambda a: a 3.默认参数:lambda a, ...
- windows服务踩的坑
最近写了一个windows服务 有一些bug最后终于解决了还是写点经验把. 第一点.版本问题,因为是小白,第一次写windows服务,选择的是.net4.6.1的目标框架,因为我的电脑是windows ...
- 剑指offer-面试题48-最长不含重复字符的子字符串-动态规划
/* 题目: 最长不含重复字符的子字符串. */ /* 思路: f(i) = f(i-1) + 1,(未出现过当前字符,distance > f(i-1) distance,当前字符和上一次出现 ...