1-2-3 skip list 确定性跳跃表的实现
/Files/rocketfan/determinsticList_readme.pdf
2 * \file determin_skip_list.h
3 * \author pku_goldenlock
4 * \date 2009-8-7
5 */
6
7 #ifndef _DETERMIN_SKIP_LIST_H
8 #define _DETERMIN_SKIP_LIST_H
9
10 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
11 TypeName( const TypeName & ); \
12 void operator = ( const TypeName & )
13
14 #include < iostream >
15// #include " skip_list.h "
16 namespace skip_list {
17
18 /* *
19 * class SkipNode.
20 * the node type for DeterminSkipList to operate.
21 */
22 template < typename ElemType >
23 class SkipNode {
24 public :
25 template < typename T > friend class DeterminSkipList;
26 SkipNode();
27 SkipNode( const ElemType & key_input, SkipNode * right_input = NULL,
28 SkipNode * down_input = NULL);
29 private :
30 DISALLOW_COPY_AND_ASSIGN(SkipNode); /* * Do not all copy and assign */
31 ElemType key; /* *< The key is what we use for comparing during Search,Insert,Remove. */
32 SkipNode * right; /* *< Point to the right skip node ont the same level */
33 SkipNode * down; /* *< Point to the lower level skip node where we will go down from current node */
34 };
35
36 template < typename ElemType >
37 SkipNode < ElemType > ::SkipNode() : right(NULL), down(NULL) {}
38
39 template < typename ElemType >
40 SkipNode < ElemType > ::SkipNode( const ElemType & key_input, SkipNode * right_input,
41 SkipNode * down_input)
42 : key(key_input), right(right_input), down(down_input) {}
43
44 /* *
45 * DeterminSkipList
46 * An implementaion of skip list using 1-2-3 skip list
47 */
48 template < typename ElemType >
49 class DeterminSkipList {
50 public :
51 /* * Client should determin Max and Max + 1 value */
52 DeterminSkipList( const ElemType & max, const ElemType & max_1);
53 ~ DeterminSkipList();
54 /* * Clear the whoe skip list free all allocated resouces on heap */
55 void Clear();
56 bool Search( const ElemType & value) const ;
57 /* *
58 * If the list already has one node whose key == value
59 * return false and do not do insert otherwise insert a new node with
60 * its key == value and return true
61 */
62 bool Insert( const ElemType & value);
63 /* *
64 * If the list already has one node whose key == value
65 * remove it and return true otherwise return false
66 */
67 bool Remove( const ElemType & value);
68 /* * For debug */
69 /* * Show the internal structure of the skip list */
70 void Print() const ;
71 /* * Return false if current structure of the skip list is wrong */
72 bool IsValid() const ;
73
74 private :
75 /* * For simplicty here do not allow copy and assign */
76 DISALLOW_COPY_AND_ASSIGN(DeterminSkipList);
77 void Init();
78 void ClearHelp(SkipNode < ElemType > * current);
79 /* *
80 * Helper function for Search
81 * If could not find one node with key value == item return bottom
82 * otherwise return postion of node containing the key
83 * */
84 SkipNode < ElemType > * SearchHelp( const ElemType & value) const ;
85 /* * Helper function for Remove, find all the nodes with key == value and modify it to other_value */
86 void FindAndModifyRemoveHelp( const ElemType & value, const ElemType & other_value);
87 /* * lower the head if possible during Remove help to keep skip list structure consistent */
88 void LowerHeadRemoveHelp();
89
90 private :
91 // actual data skip list store
92 SkipNode < ElemType > * head; /* *< where we start */
93 SkipNode < ElemType > * bottom; /* *< mark if we have down to the lowerest level */
94 SkipNode < ElemType > * tail; /* *< mark the end of each level */
95
96 const ElemType Max; /* *< Max > any client input key value */
97 const ElemType Max_1; /* *< Max_1 > Max */
98 };
99
100 template < typename ElemType >
101 DeterminSkipList < ElemType > ::DeterminSkipList( const ElemType & max, const ElemType & max_1)
102 : head(NULL), bottom(NULL), tail(NULL), Max(max), Max_1(max_1)
103 {
104 Init();
105 }
106
107 template < typename ElemType >
108 DeterminSkipList < ElemType > :: ~ DeterminSkipList()
109 {
110 if (head) {
111 Clear();
112 }
113 }
114
115 template < typename ElemType >
116 void DeterminSkipList < ElemType > ::Init()
117 {
118 // init head bottom and tail see paper p372 figure 6
119 bottom = new SkipNode < ElemType > ;
120 bottom -> right = bottom -> down = bottom;
121
122 tail = new SkipNode < ElemType > (Max_1);
123 tail -> right = tail;
124
125 head = new SkipNode < ElemType > (Max, tail, bottom);
126 }
127
128 template < typename ElemType >
129 void DeterminSkipList < ElemType > ::Clear()
130 {
131 ClearHelp(head -> down);
132 delete head;
133 delete bottom;
134 delete tail;
135 head = NULL;
136 bottom = NULL;
137 tail = NULL;
138 }
139
140 template < typename ElemType >
141 void DeterminSkipList < ElemType > ::ClearHelp(SkipNode < ElemType > * current)
142 {
143 SkipNode < ElemType > * temp;
144 if (current == bottom)
145 return ;
146 ClearHelp(current -> down);
147 while (current != tail) {
148 temp = current;
149 current = current -> right;
150 delete temp;
151 }
152 }
153
154 template < typename ElemType >
155 inline bool DeterminSkipList < ElemType > ::Search( const ElemType & value) const
156 {
157 return ((SearchHelp(value) == bottom) ? false : true );
158 }
159
160 template < typename ElemType >
161 SkipNode < ElemType > * DeterminSkipList < ElemType > ::
162 SearchHelp( const ElemType & value) const
163 {
164 SkipNode < ElemType > * current;
165
166 current = head;
167 while (current != bottom) {
168 while (value > current -> key)
169 current = current -> right;
170 if (current -> down == bottom)
171 return ((value == current -> key) ? current : bottom);
172 current = current -> down;
173 }
174 return NULL;
175 }
176
177 /* *
178 * Insert a key value to the skip list.
179 * if that the key value has already existed.
180 * return false and will not insert.
181 * else insert and return true.
182 */
183 template < typename ElemType >
184 bool DeterminSkipList < ElemType > ::Insert( const ElemType & value)
185 {
186 SkipNode < ElemType > * current, * new_node;
187
188 current = head;
189 bottom -> key = value;
190 bool can_insert = true ;
191 while (current != bottom) {
192 while (value > current -> key)
193 current = current -> right;
194 // if exists one elem whose key == value return false do not need insert
195 if ((current -> down == bottom) && (value == current -> key)) {
196 can_insert = false ; // can not insert but should check if need to adjust head before return
197 break ;
198 }
199 // if gap size is 3 or at bottom level and must insert
200 // then promote the middle element
201 if ((current -> down == bottom)
202 || (current -> key > current -> down -> right -> right -> key)) {
203 new_node = new SkipNode < ElemType > ;
204 new_node -> right = current -> right;
205 new_node -> down = current -> down -> right -> right;
206 current -> right = new_node;
207 new_node -> key = current -> key;
208 current -> key = current -> down -> right -> key;
209 }
210 current = current -> down;
211 }
212 // if need to raise the height of the skip list,raise it
213 if (head -> right != tail) {
214 new_node = new SkipNode < ElemType > ;
215 new_node -> down = head;
216 new_node -> right = tail;
217 new_node -> key = Max;
218 head = new_node;
219 }
220
221 return can_insert;
222 }
223 template < typename ElemType >
224 void DeterminSkipList < ElemType > ::FindAndModifyRemoveHelp( const ElemType & value, const ElemType & other_value)
225 {
226 SkipNode < ElemType > * current;
227
228 current = head;
229 while (current != bottom) {
230 while (value > current -> key)
231 current = current -> right;
232 if (value == current -> key)
233 current -> key = other_value;
234 current = current -> down;
235 }
236
237 }
238 template < typename ElemType >
239 void DeterminSkipList < ElemType > ::LowerHeadRemoveHelp()
240 {
241 SkipNode < ElemType > * temp;
242 if (head -> down -> right == tail) {
243 temp = head -> down;
244 head -> down = temp -> down;
245 delete temp;
246 }
247 }
248 template < typename ElemType >
249 bool DeterminSkipList < ElemType > ::Remove( const ElemType & value)
250 {
251 // empty list can not remove
252 if (head -> down == bottom)
253 return false ;
254 // current node, previous node of current, start mark the begining of each level when the node goes down
255 // if previous finally equal to start means have not advanced toward right on this level
256 // next save the start position of the next level for current node
257 SkipNode < ElemType > * current, * previous, * temp, * next;
258
259 current = head -> down;
260 int visit_num = 0 ;
261 bool can_remove = true ;
262 for (;;) { // loop and will return when curent->down == bottom
263 previous = NULL;
264 while (value > current -> key) { // try advance toward right as far as possible
265 previous = current;
266 current = current -> right;
267 }
268 // visit num will mark if a node is a height 1 node
269 if (value == current -> key)
270 visit_num ++ ;
271
272 // if on level 1 try to remove if possible and return
273 if (current -> down == bottom) {
274 if (visit_num == 0 ) { // can not find do not need to remove
275 LowerHeadRemoveHelp(); /// might need to lower the head
276 can_remove = false ;
277 return false ;
278 }
279 else { // need to remove
280 if (visit_num == 1 ) { // if node height == 1 just remove it
281 // delete need to consider down fild of the upper level
282 // so swap current and current->right
283 temp = current -> right; // to be deleted
284 current -> key = current -> right -> key;
285 current -> right = temp -> right;
286 delete temp;
287 LowerHeadRemoveHelp(); /// might need to lower the head
288 } else {
289 // if current node height > 1, swap the key with neighbour than delete the neighbour
290 // here swap with left neigbour,notice we must have advaced right on
291 // this level otherwise it must be a height 1 node.
292 // we will find all the node with key value current->key and modify it
293 // to previous->key
294 LowerHeadRemoveHelp(); // need to make sure the sturcture correct first
295 FindAndModifyRemoveHelp(current -> key, previous -> key);
296 previous -> right = current -> right;
297 delete current;
298 }
299 return true ;
300 }
301 }
302 // on other levels ,not level 1
303 // save the postion to go down on the lower level
304 next = current -> down; // the next level will be unchaged when dealing the current level
305 // current->key == current->down->right->key means the gap we want to down
306 // is of size only 1
307 if (current -> key == current -> down -> right -> key) {
308 // the first gap case, consider current gap and the next
309 if (previous == NULL) { // have not advanced on this level
310 // if the next gap has 2 or more one level lower element
311 // one element need to lower down,the other one need to raise one level,
312 // just swap do not need to delte space
313 if (current -> right -> key > current -> right -> down -> right -> key) {
314 current -> key = current -> right -> down -> key;
315 current -> right -> down = current -> right -> down -> right;
316 } else {
317 // one element need to lower down,need to delete space
318 temp = current -> right;
319 current -> key = temp -> key;
320 current -> right = temp -> right;
321 delete temp;
322 }
323 } else { // not the first so consider the privious gap and the current
324 if (previous -> key > previous -> down -> right -> key) {
325 temp = previous -> down -> right;
326 if (temp -> right -> key != previous -> key)
327 temp = temp -> right;
328 previous -> key = temp -> key;
329 current -> down = temp -> right;
330 } else {
331 previous -> key = current -> key;
332 previous -> right = current -> right;
333 delete current;
334 }
335 }
336 }
337 current = next; // go to the next level (one level lower)
338 }
339 }
340
341 template < typename ElemType >
342 bool DeterminSkipList < ElemType > ::IsValid() const
343 {
344 SkipNode < ElemType > * current, * temp, * temp2;
345 int gap_size;
346
347 current = head;
348 while (current -> down != bottom) {
349 temp = current;
350 while (temp != tail) {
351 temp2 = temp -> down;
352 gap_size = 0 ;
353 while (temp2 -> key != temp -> key) {
354 gap_size ++ ;
355 temp2 = temp2 -> right;
356 }
357 if (gap_size < 1 || gap_size > 3 )
358 return false ;
359 temp = temp -> right;
360 }
361 current = current -> down;
362 }
363 return true ;
364 }
365
366
367 template < typename ElemType >
368 void DeterminSkipList < ElemType > ::Print() const
369 {
370 using namespace std;
371 SkipNode < ElemType > * current, * temp;
372
373 current = head;
374 while (current != bottom) {
375 temp = current;
376 while (temp != NULL) {
377 if (temp != tail) {
378 cout << temp -> key << " ( "
379 << temp -> down -> key << " ) " ;
380 temp = temp -> right;
381 } else {
382 cout << temp -> key << " [ "
383 << " tail " << " ] " ;
384 temp = NULL;
385 }
386 }
387 cout << endl;
388 current = current -> down;
389 }
390 cout << endl;
391 }
392
393
394 } // end fo namespace skip_list
395
396 #endif // end of _DETERMIN_SKIP_LIST_H
2 #include < string >
3 #include < fstream >
4
5 #include " determin_skip_list.h "
6
7 using namespace std;
8 using namespace skip_list;
9
10 /* *
11 * TestSkipList is the kernal test fuction of Insert,Search and Remove of a
12 * determinstic skip list.
13 * @param skip_list is the user created empty skip list for test
14 * @param in is the ifstream relating to the opened file
15 * @param out is the ofstream relating to the file to write result
16 */
17 template < typename T >
18 void TestSkipList(DeterminSkipList < T > & skip_list, ifstream & in , ofstream & out )
19 {
20 string op;
21 string value;
22 /// loop to get input and to corresponding operation on skip_list
23 /// and write the result to the out put file
24 while ( in >> op >> value) {
25 if (op == " INS " ) {
26 if (skip_list.Insert(value))
27 out << op << " " << value << endl;
28 else
29 out << " DUP " << " " << value << endl;
30 } else if (op == " FIND " ) {
31 if (skip_list.Search(value))
32 out << op << " " << value << endl;
33 else
34 out << " NONE " << " " << value << endl;
35 } else if (op == " REM " ) {
36 if (skip_list.Remove(value))
37 out << op << " " << value << endl;
38 else
39 out << " NONE " << " " << value << endl;
40 }
41 if ( ! skip_list.IsValid())
42 cout << " not valid for " << op << " " << value << endl;
43 }
44 }
45
46 int main( int argc, char * argv[])
47 {
48 if (argc != 3 ) {
49 cout << " Usage is : "
50 << " test_determin_skip_list <input_file> <output_file> "
51 << endl;
52 return - 1 ;
53 }
54 /// argv[1] the name of the file to open
55 /// argv[2] the name of the file to wirte
56 ifstream in (argv[ 1 ]);
57 if ( ! in ) {
58 cout << " Could not find the file named "
59 << argv[ 1 ] << " to open! " << endl;
60 return - 1 ;
61 }
62 ofstream out (argv[ 2 ]);
63 /// create a empty skip list key type is string,
64 /// assumming for any input key value
65 /// key value < Max < Max_1
66 char a[2];
67 a[ 0 ] = char ( 254 ); a[ 1 ] = ' \0 ' ;
68 const string Max(a);
69 a[ 0 ] = char ( 255 );
70 const string Max_1(a);
71 DeterminSkipList < string > skip_list(Max, Max_1);
72
73 try {
74 TestSkipList(skip_list, in , out ); /// The main test process
75 } catch (std::bad_alloc & ) { /// will exit if can not allocate more space
76 cout << " no more available memory " << endl;
77 in .close();
78 out .close();
79 return - 1 ;
80 }
81
82 in .close();
83 out .close();
84 return 0 ;
85 }
1-2-3 skip list 确定性跳跃表的实现相关推荐
- 跳跃表(Skip list)原理与java实现
转载自 [算法导论33]跳跃表(Skip list)原理与java实现 Skip list是一个用于有序元素序列快速搜索的数据结构,由美国计算机科学家William Pugh发明于1989年.它的效率 ...
- 【算法导论33】跳跃表(Skip list)原理与java实现
Skip list是一个用于有序元素序列快速搜索的数据结构,由美国计算机科学家William Pugh发明于1989年.它的效率和红黑树以及 AVL 树不相上下,但实现起来比较容易.作者William ...
- java 跳跃表_c++实现跳跃表(Skip List)的方法示例
前言 Skip List是一种随机化的数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作需要O(log n)平均时间).基本上,跳跃列表是对有序的链表增加上附加的前进链接,增加是以随机 ...
- 高级数据结构与算法 | 跳跃表(Skip List)
文章目录 区间查询时链表与顺序表的局限 跳表=链表+索引 跳表的原理 晋升 插入 删除 跳表的实现 跳表VS红黑树 区间查询时链表与顺序表的局限 假设有这样一个情景, 此时需要设计一个拍卖系统,对于商 ...
- mongodb 存储过程 遍历表数据_三、redis数据存储之跳跃表(SKIP LIST)
导读 前面文章[一.深入理解redis之需要掌握的知识点 ]中,我们对redis需要学习的内容框架进行了一个梳理.[二.redis中String和List两种数据类型和应用场景 ].[二.redis中 ...
- 三、redis数据存储之跳跃表(SKIP LIST)
导读 前面文章[一.深入理解redis之需要掌握的知识点 ]中,我们对redis需要学习的内容框架进行了一个梳理.[二.redis中String和List两种数据类型和应用场景 ].[二.redis中 ...
- 用Python深入理解跳跃表原理及实现
最近看 Redis 的实现原理,其中讲到 Redis 中的有序数据结构是通过跳跃表来进行实现的.第一次听说跳跃表的概念,感到比较新奇,所以查了不少资料.其中,网上有部分文章是按照如下方式描述跳跃表的: ...
- lucene反向索引——倒排表无论是文档号及词频,还是位置信息,都是以跳跃表的结构存在的...
转自:http://www.cnblogs.com/forfuture1978/archive/2010/02/02/1661436.html 4.2. 反向信息 反向信息是索引文件的核心,也即反向索 ...
- SkipList 跳跃表
http://blog.csdn.net/likun_tech/article/details/7354306 http://www.cnblogs.com/zhuangli/articles/127 ...
最新文章
- OSC源创会往期图文回顾链接地址收藏
- HBase 与Hive数据交互整合过程详解
- Android --- PagerAdapter的使用方法详细讲解
- 需求评审五个维度框架分析及其带来的启示-2-框架原理
- ORA-12638: 身份证明检索失败
- How to resolve warning message Access restriction -The type Resource is not accessible
- 二阶振荡衰减 matlab,基于Matlab/Simulink的二阶控制系统仿真研究
- [ZJOI2011]营救皮卡丘(费用流 + 最短路)
- STM32CAN外设使用
- 关于VB.NET 菜单栏ToolStripMenu 下拉菜单单选功能的实现
- [BZOJ3684]大朋友和多叉树
- C# 6.0 新特性
- 永洪科技CEO何春涛:PASO模型构建企业大数据能力
- 全角空格可复制粘贴,解决字符对齐问题
- 一个40岁程序员的经历
- 【图像检测-缺陷检测】基于灰度共生矩阵实现痕迹检测matlab代码
- 将矩形图片绘制成圆形图片
- 【从0到1搭建LoRa物联网】8、国产LoRa终端ASR6505 PingPong通信
- 无线路由器和猫连接不上解决方案
- HRBUST1310 火影忍者之~鸣人
热门文章
- 如何分发大文件、文件夹传输解决方案
- 计算机视觉的定义,应用及整个系统
- 知乎周源微信_每周源代码18-深度缩放(Seadragon)Silverlight 2 MultiScaleImage鼠标滚轮缩放和平移版...
- 中移物联ML302 4G Cat1 模组TCP/UDP 实现流程
- 使用Python爬取微信群里的百度云资源
- 微信小程序中object类型数据的访问和赋值
- java组件 下载失败_jenkins 下载插件失败 有效的处理办法(亲测)
- OpenCV入门系列2:图像叠加、填充和腐蚀
- 【ElasticSearch教程】--- Elasticsearch文档聚合查询(十四)
- MJ评《机动2》-7.5分(土匪头象周正龙)