1. 程式人生 > >跳錶SkipList詳解

跳錶SkipList詳解

有序表的搜尋

如果要搜尋23, 43, 59要比較的次數分別為2, 4, 6次,我們把一些節點提取出來作為索引,生成如下

 

那麼搜尋43可以跳過23, 搜尋 59可以跳過23, 43;實現了搜尋的加速,提高層數

 尋找59,我們可以跳過更多的節點

調錶的實現:

  1. 搜尋時,從上往下找,上層的數作為filter,類似於二分查詢
  2. 每一個數的層數由插入時,通過一定的概率決定在多少層
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;


class SkipListNode {
public:
	int value;
	vector<SkipListNode*> nextNodes;

	SkipListNode(int v) {
		value = v;
	}
};

class SkipList {
private:
	SkipListNode* head;
	int maxLevel;
	int size;
	const double PROBABILITY = 0.5;

public:
	SkipList() {
		head = new SkipListNode(-1);
		head->nextNodes.push_back(NULL);
		maxLevel = 0;
		size = 0;		
	}

	SkipListNode* getHead() {
		return head;
	}

	bool contains(int e) {
		SkipListNode* node = find(e);
		return node != NULL && node->value != -1 && node->value == e;
	}

	void add(int newValue) {
		if (!contains(newValue)) {
			size++;
			int level = 0;
			while (rand() % 1001 / 1000.0 > PROBABILITY) {
				level++;
			}
			while (level > maxLevel) {
				head->nextNodes.push_back(NULL);
				maxLevel++;
			}
			SkipListNode* newNode = new SkipListNode(newValue);
			SkipListNode* current = head;
			do {
				current = findNext(newValue, current, level);
				newNode->nextNodes.insert(newNode->nextNodes.begin(), current->nextNodes[level]);//從第一個位置開始加入,推上去
				current->nextNodes[level] = newNode;

			} while (level-- > 0);
		}
	}

	void move(int deleteValue) {
		if (contains(deleteValue)) {
			SkipListNode* deleteNode = find(deleteValue);
			size--;
			int level = maxLevel;
			SkipListNode* current = head;
			do {
				current = findNextLess(deleteValue, current, level);
				if (deleteNode->nextNodes.size() > level) {
					current->nextNodes[level] = deleteNode->nextNodes[level];
				}
			} while (level-- > 0);
			delete deleteNode;
		}
	}




private:
	//Return the node at a given level with highest value <= e
	//刪除節點多少時候需要用
	SkipListNode* findNext(int e, SkipListNode* current, int level) {
		SkipListNode* next = current->nextNodes[level];

		while (next != NULL) {
			int value = next->value;
			if (e < value) {
				break;
			}
			current = next;
			next = current->nextNodes[level];
		}
		return current;
	}

	//Return the node at a given level with highest value < e
	SkipListNode* findNextLess(int e, SkipListNode* current, int level) {
		SkipListNode* next = current->nextNodes[level];

		while (next != NULL) {
			int value = next->value;
			if (e <= value) {
				break;
			}
			current = next;
			next = current->nextNodes[level];
		}
		return current;
	}

	SkipListNode* find(int e, SkipListNode* current, int level) {
		do {
			current = findNext(e, current, level);
		} while (level-- > 0);//保證第0層要搜尋到

		return current;
	}

	SkipListNode* find(int e) {
		return find(e, head, maxLevel);
	}
};

int main() {

	SkipList test;
	test.add(1);
	test.add(3);
	test.add(4);
	test.move(3);
	cout << test.contains(3) << endl;
	cout << test.contains(9) << endl;
	system("pause");
	return 0;
}