添加 SkipList Sbt 等样例, 完善了输出的属性列表
This commit is contained in:
parent
c032a243d8
commit
f235eb4f63
4
Makefile
4
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)
|
||||
$(CC) $(C_FLAGS) -I$(INCLUDE) -L$(LIB) $^ -o $@ $(LIBRARIES)
|
||||
|
|
1
include/skiplist
Submodule
1
include/skiplist
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit b24908c2d6e5b9a355f797cc536dd2d1c627251b
|
3
run.sh
3
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
|
||||
|
|
107
src/main.cpp
107
src/main.cpp
|
@ -6,12 +6,13 @@
|
|||
#include <string>
|
||||
#include <map>
|
||||
#include <random>
|
||||
#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<unsigned int> vec;
|
||||
vector<ULONG> vec;
|
||||
map<string, void (*)()> funcmap ;
|
||||
|
||||
void init() {
|
||||
|
@ -49,10 +50,7 @@ void init() {
|
|||
}
|
||||
|
||||
void Case1() {
|
||||
std::map<int, int> m;
|
||||
|
||||
default_random_engine e;
|
||||
std::uniform_int_distribution<> dist{0, 1000000000};
|
||||
std::map<ULONG, ULONG> 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 <Put> Benchmark" << std::endl;
|
||||
|
||||
|
||||
|
@ -72,10 +70,7 @@ void Case1() {
|
|||
}
|
||||
|
||||
void Case1_1() {
|
||||
std::map<int, int> m;
|
||||
|
||||
default_random_engine e;
|
||||
std::uniform_int_distribution<> dist{0, 1000000000};
|
||||
std::map<ULONG, ULONG> 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 <Get> Benchmark" << std::endl;
|
||||
}
|
||||
|
||||
void Case2() {
|
||||
VBTree<int, int> m(IntCompare);
|
||||
VBTree<ULONG, ULONG> 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 <Put> Benchmark" << std::endl;
|
||||
}
|
||||
|
||||
void Case2_1() {
|
||||
VBTree<int, int> m(IntCompare);
|
||||
|
||||
default_random_engine e;
|
||||
std::uniform_int_distribution<> dist{0, 1000000000};
|
||||
VBTree<ULONG, ULONG> 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 <Get> 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 <Put> 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 <find(Get)> 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 <insert(Put)> 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 <search(Get)> 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]();
|
||||
}
|
54
src/sbt.h
54
src/sbt.h
|
@ -2,25 +2,27 @@
|
|||
#include <iostream>
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user