1、什么是SkipList
2、SkipList中的概念
2.1、Node
每个节点有一个值,用于排序。并且有一个数组用于存放后面的节点。比如图1中,节点6的nexts数组大小是4, 数组的数据依次指向节点7,节点9,节点25,NIL节点。
2.2、SkipList
2.3、NIL
3、SkipList的初始化
4、SkipList的搜索
- Search(list, searchKey)
- x := list→header
- -- loop invariant: x→key < searchKey
- for i := list→level downto1 do
- whilex→forward[i]→key < searchKey do
- x := x→forward[i]
- -- x→key < searchKey ≤x→forward[1]→key
- x := x→forward[1]
- if x→key = searchKey then returnx→value
- else return failure
5、SkipList的插入和删除
- Insert(list, searchKey, newValue)
- localupdate[1..MaxLevel]
- x := list→header
- for i := list→level down to 1 do
- whilex→forward[i]→key < searchKey do
- x := x→forward[i]
- update[i] := x
- x := x→forward[1]
- if x→key = searchKey then x→value := newValue
- else
- newLevel := randomLevel()
- if newLevel > list→level then
- for i := list→level + 1 to newLevel do
- update[i] := list→header
- list→level := newLevel
- x := makeNode(newLevel , searchKey, value)
- for i := 1 tonewLevel do
- x→forward[i] := update[i]→forward[i]
- update[i]→forward[i] := x
- Delete(list, searchKey)
- local update[1..MaxLevel]
- x := list→header
- for i := list→level down to 1 do
- while x→forward[i]→key < searchKey do
- x := x→forward[i]
- update[i] := x
- x := x→forward[1]
- if x→key = searchKey then
- for i := 1 to list→level do
- if update[i]→forward[i] ≠ x then break
- update[i]→forward[i] := x→forward[i]
- free(x)
- while list→level > 1 and list→header→forward[list→level] = NIL do
- list→level := list→level – 1
6、新插入节点随机层数算法
- randomLevel()
- lvl := 1
- while random() < p and lvl < MaxLevel do
- lvl := lvl + 1
- return lvl
如果random()函数设计的足够好,那么每次random()产生的数据都有50%的概率小于1/2。也就是说层数为1的概率为100%,层数为2的概率为50%,层数为3的概率为25%,层数为4的概率为12.5%,依次衰减。所以可以看出越往上的链表,其中的节点数也就越少。
7、java版本的实现
- import java.util.ArrayList;
- import java.util.List;
- public class Node<T extends Comparable<T>> {
- private T value;
- private List<Node<T>> nexts;
- public Node(){
- this.value = null;
- this.nexts = new ArrayList<Node<T>>(0);
- }
- public Node(T value){
- this.value = value;
- this.nexts = new ArrayList<Node<T>>(0);
- }
- public Node(int size){
- this.value = null;
- this.nexts = new ArrayList<Node<T>>(size);
- }
- public void setValue(T value) {
- this.value = value;
- }
- public T getValue() {
- return value;
- }
- public void setNexts(List<Node<T>> nexts) {
- this.nexts = nexts;
- }
- public List<Node<T>> getNexts() {
- return nexts;
- }
- }
注意这里的nexts数组就是伪代码中的forward数组。
- public class SkipList<T extends Comparable<T>> {
- public static final int MAX_LEVEL = 100;
- // the head of the SkipList
- private Node<T> head = null;
- private int level = 0;
- // initial of the SkipList
- public SkipList() {
- // 初始化头部
- setHead(new Node<T>(MAX_LEVEL));
- // 初始化head的nexts数组
- for (int i = 0; i < MAX_LEVEL; i++) {
- head.getNexts().add(null);
- }
- // 设置深度
- setLevel(1);
- }
- @SuppressWarnings("unchecked")
- public void insert(T newValue) {
- if (newValue == null) {
- return;
- }
- // 更新数组
- Node<T> update[] = new Node[MAX_LEVEL];
- // 获得头部
- Node<T> p = this.head;
- int j = this.level - 1;
- while (j >= 0) {
- // 下一个节点不为NULL 并且 值小于newValue
- while ((Node<T>) p.getNexts().get(j) != null
- && newValue.compareTo(((Node<T>) p.getNexts().get(j))
- .getValue()) >= 0) {
- p = (Node<T>) p.getNexts().get(j);
- }
- update[j] = p;
- j--;
- }
- int newLevel = randomLevel();
- if (newLevel > this.level) {
- // 当newLevel大于当前的level时,设置更新数组中level到newLevel为head
- for (int i = newLevel - 1; i > level - 1; i--) {
- update[i] = this.head;
- }
- // 当newLevel大于当前的level时,需要更新当前level
- this.level = newLevel;
- }
- Node<T> newNode = new Node<T>();
- newNode.setValue(newValue);
- for (int i = 0; i < newLevel; i++) {
- newNode.getNexts().add(update[i].getNexts().get(i));
- update[i].getNexts().set(i, newNode);
- }
- }
- //获取随机层数
- private int randomLevel() {
- int level = 1;
- while (Math.random() < 1.0 / 2.0 && level < MAX_LEVEL) {
- level++;
- }
- return level;
- }
- public void setHead(Node<T> head) {
- this.head = head;
- }
- public Node<T> getHead() {
- return head;
- }
- public void setLevel(int level) {
- this.level = level;
- }
- public int getLevel() {
- return level;
- }
- public static void main(String[] args) {
- SkipList<Integer> skip = new SkipList<Integer>();
- for (int i = 0; i < 10; i++) {
- skip.insert(new Integer(i));
- }
- }
- }
转自:http://blog.youkuaiyun.com/xlnjulp/article/details/25376015
2428



被折叠的 条评论
为什么被折叠?



