skip.h
来自「一本全面剖析C++数据结构算法的书籍」· C头文件 代码 · 共 172 行
H
172 行
// file skip.h#ifndef SkipList_#define SkipList_#include <stdlib.h>#include <iostream.h>#include <math.h>#include "xcept.h"#include "skipnode.h"template<class E, class K>class SkipList { public: SkipList(K Large, int MaxE = 10000, float p = 0.5); ~SkipList(); bool Search(const K& k, E& e) const; SkipList<E,K>& Insert(const E& e); SkipList<E,K>& Delete(const K& k, E& e); void Output(); private: int Level(); SkipNode<E,K> *SaveSearch(const K& k); int MaxLevel; // max permissible chain level int Levels; // max current nonempty chain int CutOff; // used to decide level number K TailKey; // a large key SkipNode<E,K> *head; // head node pointer SkipNode<E,K> *tail; // tail node pointer SkipNode<E,K> **last; // array of pointers};template<class E, class K>SkipList<E,K>::SkipList(K Large, int MaxE, float p){// Constructor. CutOff = p * RAND_MAX; MaxLevel = ceil(log(MaxE) / log(1/p)) - 1; TailKey = Large; Levels = 0; // initial number of levels // create head & tail nodes and last array head = new SkipNode<E,K> (MaxLevel+1); tail = new SkipNode<E,K> (0); last = new SkipNode<E,K> *[MaxLevel+1]; tail->data = Large; // head points to tail at all levels as empty for (int i = 0; i <= MaxLevel; i++) head->link[i] = tail;}template<class E, class K>SkipList<E,K>::~SkipList(){// Delete all nodes and array last. SkipNode<E,K> *next; // delete all nodes by deleting level 0 while (head != tail) { next = head->link[0]; delete head; head = next; } delete tail; delete [] last;}template<class E, class K>bool SkipList<E,K>::Search(const K& k, E& e) const{// Search for element that matches k. // Put matching element in e. // Return false if no match. if (k >= TailKey) return false; // position p just before possible node with k SkipNode<E,K> *p = head; for (int i = Levels; i >= 0; i--) // go down levels while (p->link[i]->data < k) // follow level i p = p->link[i]; // pointers // check if next node has key k e = p->link[0]->data; return (e == k);}template<class E, class K>SkipNode<E,K> * SkipList<E,K>::SaveSearch(const K& k){// Search for k and save last position // visited at each level. // position p just before possible node with k SkipNode<E,K> *p = head; for (int i = Levels; i >= 0; i--) { while (p->link[i]->data < k) p = p->link[i]; last[i] = p; // last level i node seen } return (p->link[0]);}template<class E, class K>int SkipList<E,K>::Level(){// Generate a random level number <= MaxLevel. int lev = 0; while (rand() <= CutOff) lev++; return (lev <= MaxLevel) ? lev : MaxLevel;}template<class E, class K>SkipList<E,K>& SkipList<E,K>::Insert(const E& e){// Insert e if not duplicate. K k = e; // extract key if (k >= TailKey) throw BadInput(); // too large // see if duplicate SkipNode<E,K> *p = SaveSearch(k); if (p->data == e) throw BadInput(); // duplicate // not duplicate, determine level for new node int lev = Level(); // level of new node // fix lev to be <= Levels + 1 if (lev > Levels) {lev = ++Levels; last[lev] = head;} // get and insert new node just after p SkipNode<E,K> *y = new SkipNode<E,K> (lev+1); y->data = e; for (int i = 0; i <= lev; i++) { // insert into level i chain y->link[i] = last[i]->link[i]; last[i]->link[i] = y; } return *this;}template<class E, class K>SkipList<E,K>& SkipList<E,K>::Delete(const K& k, E& e){// Delete element that matches k. Put deleted // element in e. Throw BadInput if no match. if (k >= TailKey) throw BadInput(); // too large // see if matching element present SkipNode<E,K> *p = SaveSearch(k); if (p->data != k) throw BadInput(); // not present // delete node from skip list for (int i = 0; i <= Levels && last[i]->link[i] == p; i++) last[i]->link[i] = p->link[i]; // update Levels while (Levels > 0 && head->link[Levels] == tail) Levels--; e = p->data; delete p; return *this;}template<class E, class K>void SkipList<E,K>::Output(){ SkipNode<E,K> *y = head->link[0]; for (; y != tail; y = y->link[0]) cout << y->data << ' '; cout << endl;}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?