Reprint Please specify: http://blog.csdn.net/ict2014/article/details/17394259
Skiplist is widely used in leveldb and lucence, and is a more efficient data structure. Because of its code and the simplicity of the implementation of the principle, it is more acceptable. Let's first look at the definition of skiplist and why it's called a jumping table.
"Skip lists is data structures that use probabilistic balancing rather than strictly enforced balancing. As a result, the algorithms for insertion and deletion in skip lists is much simpler and significantly faster than Equivalent algorithms for balanced trees. ”
Jumping tables use probabilistic equalization instead of mandatory equalization, so it is more concise and efficient to insert and delete nodes than traditional balanced tree algorithms.
Let's look at a diagram to see what a jump table is, as shown in Figure 1:
Figure 1: A simple example of a jumping table
As shown above, it is a simple jumping table. The traditional single-linked list is a linear structure, where an O (n) time is required to insert a node into an ordered list, and an O (n) time is required for the lookup operation. If we use the Jump table shown in Figure 1, we can reduce the time required for the lookup to O (N/2), because we can skip the half of the nodes by first looking through the topmost pointers of each node. For example we want to find 19, first and 6 comparison, greater than 6 after the comparison with 9, and then in and 12 to compare ... At the end of the comparison to 21, found that 21 is greater than 19, indicating that the point of the search between 17 and 21, from this process, we can see that the time of the search jumped over 3, 7, 12 and other points, so the complexity of the search is O (N/2). The process of finding is as follows in Figure 2:
Figure 2: A simple example of a skip table lookup operation
In fact, the above is basically the idea of jumping table, each node is not only a pointer to the next node, may contain a number of pointers to subsequent nodes, so that you can skip some unnecessary nodes, so as to speed up the search, delete and other operations. For each node in a list that contains pointers to subsequent elements, the process is obtained from a random function generator, which forms a jumping table. This is why the paper "Skip lists:a probabilistic alternative to Balanced Trees" has the "probability" of the cause, that is, by randomly generating a node in the number of pointers to subsequent nodes. The randomly generated jump table may look like Figure 3 below:
Figure 3: Randomly generated jump tables
The general principle of jumping table, we will tell here. Below we will discuss the operation of jumping table from the following aspects:
1. Important Data Structure definition
2. Initialization table
3. Find
4. Insert
5. Delete
6. Random number generator
7. Release Form
8. Performance Comparison
(i) Definition of important data structures
from Figure 3, we can see that a jumping table is made up of nodes, and nodes are linked by pointers. So we define the following data structure:
[CPP] view plain copy print? Defines the type of key and value typedef int KEYTYPE; typedef int VALUETYPE; Defines the node typedef struct NODESTRUCTURE* node; struct nodestructure{KeyType key; ValueType value; Node Forward[1]; }; Define a jump table typedef struct LISTSTRUCTURE* List; struct liststructure{int level; Node header; }; Each node is made up of 3 parts, key (keyword), value (stored values), and forward array (an array that points to subsequent nodes, where only the first address is saved). With these nodes, we can create a list of jump tables, consisting of two elements, the first node and level (the largest number of layers or heights in the current jump table). In this way, the basic data structure definition is complete.
(ii) Initialize table
Initialization table mainly includes two aspects, first, the header node and nil node application, followed by the list resource application.
[CPP] View plain copy print? Void skiplist::newlist () { //set NIL junction newnodewithlevel (0, nil_); NIL_->key = 0x7fffffff; //set list of linked list list_ = (list) malloc (sizeof (liststructure)); list_->level = 0; //set head node newnodewithlevel (Max_level,list_->header); for (int i = 0; i < max_level; ++i) { list_->header->forward[i] = NIL_; }