本來跳表的原理很easy的(相對於紅 - 黑樹),但國慶間歇性地搞5天才撈起來……
我學會了跳之前寫表的鏈式結構完全基於,我看著寫的過程中redis實現,它的每個鍵列都是用陣列來表示的。細緻想了想發現這樣的實現除了跳表的最大層數會被固定(由於是用的陣列)之外,在效能、**簡潔性方面都是很好的。並且實際使用中。可能也並不希望跳表的層數毫無限制地增長。
只是最後我自己的實現還是依照純粹鏈式結構實現,由於陣列的方式redis已經實現過了。
關於跳表原理網上非常多,這裡不再贅述。**疏漏之處懇請指出。
/** * @return 新建的的空跳表例項
*/skip_list_t
skip_list_create();
/** * 銷毀跳表例項,不會銷毀跳表中包括的值。
*/void
skip_list_destroy(skip_list_t sl);
/** * 查詢跳表中key相應的值。
* 返回null不代表跳表中一定不包括key。以skip_list_contains(sl, key)結果為準。
* @param key 要查詢的鍵。同意key在跳表中不存在。
* @return 跳表中key相應的值 */ void* skip_list_get(skip_list_t sl, int key); /** * 向跳表中加入乙個鍵值對,這將使得skip_list_contains(sl, key)==1。 * 假設跳表中已經存在同樣的鍵,則替換其舊值,否則建立乙個新的鍵值對。 * @param value key相應的新的值,同意為null。
* @return 跳表中key原來相應的值 */ void* skip_list_put(skip_list_t sl, int key, void *value); /** * 從跳表中刪除乙個鍵值對,這將使得skip_list_contains(sl, key)==0。 * @param key 要刪除的鍵,同意key在跳表中不存在。 * @return 跳表中key相應的值 */ void* skip_list_remove(skip_list_t sl, int key); /** * @return 跳表中存在key則1,否則0 */ int skip_list_contains(skip_list_t sl, int key); /** * @return 跳表中鍵的數量 */ int skip_list_count(skip_list_t sl); /** * 檢索跳表中鍵的集合。結果依照鍵公升序排列 * @param [out] keys 用於儲存鍵集合 * @param [int] length keys陣列的長度 * @return 鍵的數量(=min(length, 跳表中全部鍵的數量)) */ int skip_list_key_set(skip_list_t sl, int keys, int length); /** * 檢索跳表中值的集合,結果依照鍵公升序排列 * @param [out] values 用於儲存值集合 * @param [int] length values陣列的長度 * @return 值的數量(=min(length, 跳表中全部鍵的數量)) */ int skip_list_value_set(skip_list_t sl, void *values, int length); #endif // skip_list_h_included
#include #include #include #include "skip_list.h"
#define count 10
int main() ;
//表示跳表中的節點
struct node_s ;
//依照二叉查詢樹的概率分布隨機生成乙個節點高度
static inline int
rand_level()
return level;
}//從node右邊開始逐層向下查詢key相應的鍵值對
//在某一層找到以後馬上返回,以提高查詢速度
//node不能為null
static inline data_t
search_data(node_t node, int key)
} return null;
}//從node右邊開始逐層向下查詢key相應的鍵值對,並將垂直路徑記錄在upadte陣列中
//必須走到最底層以後才返回,以便記錄完整的update路徑
//node和update不能為null
static inline data_t
search_data_update(node_t node, int key, node_t *update)
} if(node->right && key == node->right->data->key)
return null;
}//在跳表最頂層上面新增一些空層
//top_left不能為null,效能能夠改進
static inline int
gain_empty_top_lines(node_t top_left, int count)
return i;
}//清除跳表最頂層的幾個空層
//top_left不能為null。效能能夠改進
static inline int
clean_empty_top_lines(node_t top_left)
top_left->right = tmp->right;
top_left->down = tmp->down;
free(tmp);
} return count;
}//在跳表中為新的鍵值對新增一列位置
//data和update不能為null
static inline void
add_key_column(data_t data, node_t *update, int length)
for(i=0; iright->down = update[i+1]->right;
} update[length-1]->right->down = null;
}//在跳表中刪除key所在的列
//update不能為null
static inline void
remove_key_column(int key, node_t *update, int length) }}
//釋放節點並返回它的下乙個(右邊或下邊)節點
static inline node_t
free_and_next(node_t node, node_t next)
struct skip_list_s ;
skip_list_t
skip_list_create()
void
skip_list_destroy(skip_list_t sl)
for(node = left->right; node; node = free_and_next(node, node->right));
for(left = sl->top_left.down; left; left = free_and_next(left, left->down));
free(sl);
}void*
skip_list_get(skip_list_t sl, int key)
return null;
}void*
skip_list_put(skip_list_t sl, int key, void *value) else
update = (node_t*)malloc(sizeof(node_t)*sl->level);
search_data_update(&sl->top_left, key, update);
data = (data_t)malloc(sizeof(struct data_s));
data->key = key;
data->value = value;
//target_level<=sl->level
add_key_column(data, update+(sl->level-target_level), target_level);
free(update);
sl->count++;
} return old_value;
}void*
skip_list_remove(skip_list_t sl, int key)
free(update);
return old_value;
}int
skip_list_contains(skip_list_t sl, int key)
intskip_list_count(skip_list_t sl)
intskip_list_key_set(skip_list_t sl, int keys, int length)
return i;
}int
skip_list_value_set(skip_list_t sl, void *values, int length)
return i;
}
C語言 函式指標 三 跳轉表
跳轉表就是乙個函式指標陣列。建立乙個跳轉表需要兩個步驟。1 首先,宣告並初始化乙個函式指標陣列,唯一需要留心之處就是確保這些函式的原型出現在這個陣列的宣告之前 2 使用下面的語句替換 switch 語句 result switch table num value1,value2 num 用於從陣列中...
順序表應用 純C語言版本
說明 今天整理了一下順序表的題目,一共是十道題,有一些題目用的是相同的演算法,但是也是能ac的,先獻上 後序再補上其他演算法的 include include int a 10010 void creat int n int moved int a,int n n j return n int ma...
線性表玩具之鍊錶版本 C語言
2009年3月26日 12 41 slyar 本來不想發這麼水的 可是最近也沒什麼好寫的.純當湊文章數目吧.這是乙個線性表操作的小玩具,此篇為鍊錶版本,也就是用指標和動態記憶體分配的。123 4567 891011 1213 1415 1617 1819 2021 2223 2425 2627 28...