跳表的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 前言 跳表是面试常问的一种数据结构,它在很多中间件和语言中得到应用,我们 ...
随机推荐
- 细读jsr中的yield语义,或者不是我们想象中的那样
这只是我的个人观点,如有错误,希望你可以指出. 首先英文原版 中文译版 我觉得“不需要”还会让人产生误解,应该译为不一定要. 很多时候会被断章取义地理解,我们一定要有“不一定”,“可能”的意识,下面给 ...
- Deepin下将Caps映射为Control_L键
xmodmap -e 'clear Lock' -e 'keycode 0x42 = Control_L'
- 实训第八天 有关python orm 的学习记录 常用方法02
继续沿用第七天数据库:def test2(request): # 1.xxx__lt 小于 :查询出年龄小于22的所有 ret=models.Person.objects.filter(age__lt ...
- linux中文件处理命令
目录 touch cat more less head tail touch 解释 命令名称:touch 命令所在路径:/bin/touch 执行权限:所有用户 功能描述:创建空文件 语法 touch ...
- Nginx Rewrite相关功能
目录 Nginx Rewrite相关功能 ngx_http_rewrite_module模块指令: if指令: set指令: break指令: return指令: rewrite_log指令: rew ...
- Python3标准库:weakref对象的非永久引用
1. weakref对象的非永久引用 weakref模块支持对象的弱引用.正常的引用会增加对象的引用数,并避免它被垃圾回收.但结果并不总是如期望中的那样,比如有时可能会出现一个循环引用,或者有时需要内 ...
- 手动发布本地jar包到Nexus私服
1.Nexus配置 1. 在Nexus私服上建立仓库,用于盛放jar包,如名叫3rd_part. 2. 注册用户Nuxus用户,如名叫dev,密码dev_123. 3. 给dev用户分配能访问3rd_ ...
- WebStorm新建JS文件、CSS文件时自动生成文件注释
WebStorm 是jetbrains公司旗下一款优秀的前端开发工具.随着现在大型项目模块越来越多,参与人员也越来越多,实际项目中经常需要明确文件用途和文件的归属,所以创建文件时添加文件注释是一种必要 ...
- SynchronizationContext(同步上下文)综述
>>返回<C# 并发编程> 1. 概述 2. 同步上下文 的必要性 2.1. ISynchronizeInvoke 的诞生 2.2. SynchronizationContex ...
- 简单IOC容器实现
前言 本文是为了学习Spring IOC容器的执行过程而写,不能完全代表Spring IOC容器,只是简单实现了容器的依赖注入和控制反转功能,无法用于生产,只能说对理解Spring容器能够起到一定的作 ...