跳跃表是基于链表外挂索引的一种实现,为解决链表遍历慢的问题,当数据链表的连续存储长度超过一定数量之后,将其中某一节点提为索引节点,数据节点与数据节点相关联,索引节点与索引节点相关联,索引节点管理目标数据节点。这里仅实现了单索引层,本来想实现动态增加索引层结果脑子不够用,大家当伪码看一下就行了。
节点构造为数据本身,前驱节点,后继节点,up节点(用于实现数据节点对索引节点的关联),down节点(用于索引节点对数据节点的关联)
private int info; private Point front=null; private Point next=null; private Point up=null; private Point down=null;
用于存储数据根节点,和索引根节点
private Point root; private Point indexRoot;
根据递增的规则,比next大的就往后传, 处于当前节点和下一节点这一区间则插入两节点之间
public void add(int num){ if(this.next!=null && this.info<num){ if(this.next.info>num){ Point p = new Point(num); p.front = this; p.next = this.next; this.next.front = p; this.next = p; } if(this.next.info<num){ this.next.add(num); } } if(this.next==null && this.info<num){ Point p = new Point(num); this.next = p; p.front = this; } if(this.info>num){ Point p = new Point(num); this.setRoot(p); p.next=this; this.front=p; } if(this.up==null){ checkindex(); } if(this.getRoot().equals(this) && this.up==null){ Point p = new Point(this.info); this.up = p; p.down = this; this.setIndexRoot(p); } }
每个节点向前五个节点遍历,若发现连续5个节点都没有构造索引,则将当前节点作为索引进行构造,并将构造出来索引节点与当前节点进行关联并由根索引节点插入
private void checkindex(){ int i=5; Point p = this; while(i>0){ if(this.front!=null){ p=this.front; } if(p.up!=null){ return; } i--; } this.getIndexRoot().add(this.info); Point p1 = this.getIndexRoot().creatCon(this.info); p1.down = this; this.up = p1; } private Point creatCon(int num){ if(this.getInfo()!=num){ return this.next.creatCon(num); } if(this.getInfo()==num){ return this; } return null; }
查找方法由索引根节点开始,若值处于当前节点与下一节点之间则将该节点传入当前索引节点所对应的数据节点处继续进行查找方法,否则向下一索引节点传递
public Point find(int num){ if(this.info == num){ return this; } if(this.info < num && this.next.info>num){ this.down.find(num); } if(this.next.info<num){ this.next.find(num); } return null; }
节点类
package SkipList; public class Point extends SkipList { private int info; private Point front=null; private Point next=null; private Point up=null; private Point down=null; private Point(int num){ this.info = num; } public Point find(int num){ if(this.info == num){ return this; } if(this.info < num && this.next.info>num){ this.down.find(num); } if(this.next.info<num){ this.next.find(num); } return null; } public void add(int num){ if(this.next!=null && this.info<num){ if(this.next.info>num){ Point p = new Point(num); p.front = this; p.next = this.next; this.next.front = p; this.next = p; } if(this.next.info<num){ this.next.add(num); } } if(this.next==null && this.info<num){ Point p = new Point(num); this.next = p; p.front = this; } if(this.info>num){ Point p = new Point(num); this.setRoot(p); p.next=this; this.front=p; } if(this.up==null){ checkindex(); } if(this.getRoot().equals(this) && this.up==null){ Point p = new Point(this.info); this.up = p; p.down = this; this.setIndexRoot(p); } } private void checkindex(){ int i=5; Point p = this; while(i>0){ if(this.front!=null){ p=this.front; } if(p.up!=null){ return; } i--; } this.getIndexRoot().add(this.info); Point p1 = this.getIndexRoot().creatCon(this.info); p1.down = this; this.up = p1; } private Point creatCon(int num){ if(this.getInfo()!=num){ return this.next.creatCon(num); } if(this.getInfo()==num){ return this; } return null; } public int getInfo() { return info; } public void setInfo(int info) { this.info = info; } public Point getFront() { return front; } public void setFront(Point front) { this.front = front; } public Point getNext() { return next; } public void setNext(Point next) { this.next = next; } public Point getUp() { return up; } public void setUp(Point up) { this.up = up; } public Point getDown() { return down; } public void setDown(Point down) { this.down = down; } }
链表类
package SkipList; public class SkipList { private Point root; private Point indexRoot; public Point getRoot() { return root; } public void setRoot(Point root) { this.root = root; } public void add(int num){ this.root.add(num); } public Point getIndexRoot() { return indexRoot; } public void setIndexRoot(Point p){ this.indexRoot = p; } }