diff --git a/Makefile b/Makefile index 5193e0e..91da475 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC := g++ -C_FLAGS := -std=c++17 -Wall -Wextra -g -O2 +C_FLAGS := -std=c++17 -Wall -Wextra -g -O2 -Wno-unused-parameter -Wno-unused-function BIN := bin SRC := src @@ -23,4 +23,4 @@ run: all ./$(BIN)/$(EXECUTABLE) $(BIN)/$(EXECUTABLE): $(SRC)/* - $(CC) $(C_FLAGS) -I$(INCLUDE) -L$(LIB) $^ -o $@ $(LIBRARIES) \ No newline at end of file + $(CC) $(C_FLAGS) -I$(INCLUDE) -L$(LIB) $^ -o $@ $(LIBRARIES) diff --git a/include/skiplist b/include/skiplist new file mode 160000 index 0000000..b24908c --- /dev/null +++ b/include/skiplist @@ -0,0 +1 @@ +Subproject commit b24908c2d6e5b9a355f797cc536dd2d1c627251b diff --git a/run.sh b/run.sh index 977e08d..f708d31 100644 --- a/run.sh +++ b/run.sh @@ -1,5 +1,8 @@ +make clean all ./bin/main 1 ./bin/main 1_1 ./bin/main 2 ./bin/main 2_1 ./bin/main 3 +./bin/main 3_1 +./bin/main 4 diff --git a/src/main.cpp b/src/main.cpp index 7852cf1..193c4a3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,12 +6,13 @@ #include #include #include +#include "skiplist/skiplist.h" using namespace std; using chrono::high_resolution_clock; using std::string; -int IntCompare(int v1, int v2) { +int IntCompare(ULONG v1, ULONG v2) { if (v1 > v2) { return 1; } else if (v1 < v2) { @@ -23,7 +24,7 @@ int IntCompare(int v1, int v2) { const ULONG N = 5000000; -vector vec; +vector vec; map funcmap ; void init() { @@ -49,10 +50,7 @@ void init() { } void Case1() { - std::map m; - - default_random_engine e; - std::uniform_int_distribution<> dist{0, 1000000000}; + std::map m; high_resolution_clock::time_point t1 = high_resolution_clock::now(); //返回时间戳 @@ -64,7 +62,7 @@ void Case1() { high_resolution_clock::time_point t2 = high_resolution_clock::now(); //返回时间戳 - std::cout << (t2 - t1).count() / N << std::endl; + std::cout << (t2 - t1).count() / N << " ns/op" << std::endl; std::cout << "end RBTree Case Benchmark" << std::endl; @@ -72,10 +70,7 @@ void Case1() { } void Case1_1() { - std::map m; - - default_random_engine e; - std::uniform_int_distribution<> dist{0, 1000000000}; + std::map m; for (ULONG i = 0; i < N; i++) { auto v = vec[i]; @@ -92,12 +87,12 @@ void Case1_1() { high_resolution_clock::time_point t2 = high_resolution_clock::now(); //返回时间戳 - std::cout << (t2 - t1).count() / N << std::endl; + std::cout << (t2 - t1).count() / N << " ns/op" << std::endl; std::cout << "end RBTree Case Benchmark" << std::endl; } void Case2() { - VBTree m(IntCompare); + VBTree m(IntCompare); high_resolution_clock::time_point t1 = high_resolution_clock::now(); //返回时间戳 @@ -108,15 +103,12 @@ void Case2() { high_resolution_clock::time_point t2 = high_resolution_clock::now(); //返回时间戳 - std::cout << (t2 - t1).count() / N << std::endl; + std::cout << (t2 - t1).count() / N << " ns/op" << std::endl; std::cout << "end VBTree Case Benchmark" << std::endl; } void Case2_1() { - VBTree m(IntCompare); - - default_random_engine e; - std::uniform_int_distribution<> dist{0, 1000000000}; + VBTree m(IntCompare); for (ULONG i = 0; i < N; i++) { auto v = vec[i]; @@ -133,16 +125,13 @@ void Case2_1() { high_resolution_clock::time_point t2 = high_resolution_clock::now(); //返回时间戳 - std::cout << (t2 - t1).count() / N << std::endl; + std::cout << (t2 - t1).count() / N << " ns/op" << std::endl; std::cout << "end VBTree Case Benchmark" << std::endl; } void Case3() { BinaryTree tree; - default_random_engine e; - std::uniform_int_distribution<> dist{0, 1000000000}; - high_resolution_clock::time_point t1 = high_resolution_clock::now(); //返回时间戳 @@ -153,10 +142,75 @@ void Case3() { high_resolution_clock::time_point t2 = high_resolution_clock::now(); //返回时间戳 - std::cout << (t2 - t1).count() / N << std::endl; + std::cout << (t2 - t1).count() / N << " ns/op" << std::endl; std::cout << "end SBT Case Benchmark" << std::endl; } +void Case3_1() { + BinaryTree tree; + + for (ULONG i = 0; i < N; i++) { + auto v = vec[i]; + tree.insert(v); + } + + high_resolution_clock::time_point t1 = + high_resolution_clock::now(); //返回时间戳 + + for (auto iter = vec.begin(); iter != vec.end(); iter++) { + tree.find(*iter); + } + + high_resolution_clock::time_point t2 = + high_resolution_clock::now(); //返回时间戳 + + std::cout << (t2 - t1).count() / N << " ns/op" << std::endl; + std::cout << "end SBT Case Benchmark" << std::endl; +} + +void Case4() { + struct skiplist *list = skiplist_new(); + + high_resolution_clock::time_point t1 = + high_resolution_clock::now(); //返回时间戳 + + for (ULONG i = 0; i < N; i++) { + auto v = vec[i]; + skiplist_insert(list, v, v); + } + high_resolution_clock::time_point t2 = + high_resolution_clock::now(); //返回时间戳 + + std::cout << (t2 - t1).count() / N << " ns/op" << std::endl; + std::cout << "end SkipList Case Benchmark" << std::endl; +} + +void Case4_1() { + struct skiplist *list = skiplist_new(); + + for (ULONG i = 0; i < N; i++) { + auto v = vec[i]; + skiplist_insert(list, v, v); + } + + + high_resolution_clock::time_point t1 = + high_resolution_clock::now(); //返回时间戳 + + for (auto iter = vec.begin(); iter != vec.end(); iter++) { + skiplist_search(list, *iter); + } + + high_resolution_clock::time_point t2 = + high_resolution_clock::now(); //返回时间戳 + + + std::cout << (t2 - t1).count() / N << " ns/op" << std::endl; + std::cout << "end SkipList Case Benchmark" << std::endl; +} + + + int main(int argc, char *argv[]) { init(); @@ -167,8 +221,13 @@ int main(int argc, char *argv[]) { funcmap["2_1"] = Case2_1; funcmap["3"] = Case3; + funcmap["3_1"] = Case3_1; - cout << argv[1] << endl; + funcmap["4"] = Case4; + funcmap["4_1"] = Case4_1; + + cout << endl; + cout << "case: " << argv[1] << endl; string fname = argv[1]; funcmap[fname](); } \ No newline at end of file diff --git a/src/sbt.h b/src/sbt.h index 190ecc6..8126599 100644 --- a/src/sbt.h +++ b/src/sbt.h @@ -2,25 +2,27 @@ #include using namespace std; +typedef unsigned long ULONG; + class SBTNode { public: //size:子树大小(就是以当前结点为根构成的树有多少结点) //data:权值,就是树上的结点储存的值 //value:应该是临时储存权值的 - int data, size, value; + ULONG data, size, value; SBTNode * lchild, * rchild, * father; //构造函数,参数分别为 权值,以当前结点为根的树的大小,父亲结点 - SBTNode(int init_data, int init_size = 0, SBTNode * init_father = NULL); + SBTNode(ULONG init_data, ULONG init_size = 0, SBTNode * init_father = NULL); ~SBTNode(); //下面依次是 //二叉排序树的插入,搜索,找前驱,找后继,移除某个度为0或1的结点,移除某个权值的点,找出第k大的元素 - void insert(int value); - SBTNode * search(int value); + void insert(ULONG value); + SBTNode * search(ULONG value); SBTNode * predecessor(); SBTNode * successor(); void remove_node(SBTNode * delete_node); - bool remove(int value); - int select(int k); + bool remove(ULONG value); + ULONG select(ULONG k); }; class BinaryTree { @@ -31,17 +33,17 @@ public: ~BinaryTree(); //下面依次是 //二叉树的插入 查找 删除结点 找出第k大的树,都是以上面的结点类的函数为基础的 - void insert(int value); - bool find(int value); - bool remove(int value); - int select(int k); + void insert(ULONG value); + bool find(ULONG value); + bool remove(ULONG value); + ULONG select(ULONG k); }; //这里搞了个权值为0的结点,避免在边界情况时对空指针(NULL)进行特判,所以将所有原本指向空指针的情况都改为指向一个 ZPTR,并将其 size 设置为 0,从而降低代码复杂度。 SBTNode ZERO(0); SBTNode * ZPTR = &ZERO; -SBTNode::SBTNode(int init_data, int init_size, SBTNode * init_father) { +SBTNode::SBTNode(ULONG init_data, ULONG init_size, SBTNode * init_father) { data = init_data; size = init_size; lchild = ZPTR; @@ -108,7 +110,7 @@ SBTNode * right_rotate(SBTNode * node) { //利用上面的左右旋进行调整的函数 //flag为false:处理左子树更高的情况,否则处理右子树更高的情况 //node:要调整的子树的根结点 -SBTNode * maintain(SBTNode * node, bool flag) { +SBTNode * maULONGain(SBTNode * node, bool flag) { //左子树比右子树高(或者叫深度要深) if (flag == false) { //LL型:左子树的左子树的元素个数大于右子树的元素个数,应进行右旋 @@ -150,17 +152,17 @@ SBTNode * maintain(SBTNode * node, bool flag) { //递归调用,处理可能左子树的左子树高度更高的情况 //false表示左子树较高 - node->lchild = maintain(node->lchild, false); + node->lchild = maULONGain(node->lchild, false); //其右子树的右子树高度更高的情况 - node->rchild = maintain(node->rchild, true); + node->rchild = maULONGain(node->rchild, true); //最后再对子树根结点的左右子树递归进行调整 - node = maintain(node, false); - node = maintain(node, true); + node = maULONGain(node, false); + node = maULONGain(node, true); //返回调整后的子树的根结点 return node; } -SBTNode * insert(SBTNode * node, int value) { +SBTNode * insert(SBTNode * node, ULONG value) { if (value == node->data) { return node; } else { @@ -179,10 +181,10 @@ SBTNode * insert(SBTNode * node, int value) { } } } - return maintain(node, value > node->data); + return maULONGain(node, value > node->data); } -SBTNode * SBTNode::search(int value) { +SBTNode * SBTNode::search(ULONG value) { if (data == value) { return this; } else if (value > data) { @@ -242,7 +244,7 @@ void SBTNode::remove_node(SBTNode * delete_node) { delete delete_node; } -bool SBTNode::remove(int value) { +bool SBTNode::remove(ULONG value) { SBTNode * delete_node, * current_node; current_node = search(value); if (current_node == ZPTR) { @@ -261,9 +263,9 @@ bool SBTNode::remove(int value) { return true; } -int SBTNode::select(int k) { +ULONG SBTNode::select(ULONG k) { //rank表示当前结点在子树的排位 - int rank = lchild->size + 1; + ULONG rank = lchild->size + 1; //若rank等于第k小的k,说明就是要找的值,直接返回权值即可 if (rank == k) { return data; @@ -288,7 +290,7 @@ BinaryTree::~BinaryTree() { } } -void BinaryTree::insert(int value) { +void BinaryTree::insert(ULONG value) { if (root == NULL) { //初始化时只有根结点,所以子树大小为1 root = new SBTNode(value, 1); @@ -297,7 +299,7 @@ void BinaryTree::insert(int value) { } } -bool BinaryTree::find(int value) { +bool BinaryTree::find(ULONG value) { if (root->search(value) == NULL) { return false; } else { @@ -305,10 +307,10 @@ bool BinaryTree::find(int value) { } } -bool BinaryTree::remove(int value) { +bool BinaryTree::remove(ULONG value) { return root->remove(value); } -int BinaryTree::select(int k) { +ULONG BinaryTree::select(ULONG k) { return root->select(k); }