初始化
This commit is contained in:
parent
09b7033587
commit
50d5d5c09f
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -114,3 +114,6 @@ dkms.conf
|
|||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
#my
|
||||
build
|
||||
|
||||
|
|
49
.vscode/launch.json
vendored
Normal file
49
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) main debug",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/orderly",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "cmake main debug",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "为 gdb 启用整齐打印",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "(gdb) gtest bug",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/gtest/build/vbt_test",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "cmake test debug",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "为 gdb 启用整齐打印",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"C_Cpp.default.configurationProvider": "vector-of-bool.cmake-tools"
|
||||
}
|
39
.vscode/tasks.json
vendored
Normal file
39
.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "cmake main debug",
|
||||
"command": "/usr/bin/bash",
|
||||
"args": [
|
||||
"-c",
|
||||
"cd ${workspaceFolder}/build && cmake .. && make -j4",
|
||||
],
|
||||
"options": {
|
||||
"cwd": "/bin"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "cmake test debug",
|
||||
"command": "/usr/bin/bash",
|
||||
"args": [
|
||||
"-c",
|
||||
"cd ${workspaceFolder}/gtest && mkdir -p build && cd build && cmake .. && make -j4",
|
||||
],
|
||||
"options": {
|
||||
"cwd": "/bin"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
24
CMakeLists.txt
Normal file
24
CMakeLists.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
cmake_minimum_required(VERSION 3.5.0)
|
||||
project(orderly VERSION 0.1.0)
|
||||
|
||||
include(CTest)
|
||||
enable_testing()
|
||||
|
||||
include(GoogleTest)
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_LIST_DIR}/src
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
link_directories(
|
||||
/usr/lib/
|
||||
/usr/local/lib/
|
||||
)
|
||||
|
||||
add_subdirectory(gtest)
|
||||
add_executable(orderly src/main.cpp)
|
||||
|
||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
||||
include(CPack)
|
17
gtest/CMakeLists.txt
Normal file
17
gtest/CMakeLists.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_LIST_DIR}/../src
|
||||
)
|
||||
|
||||
include(GoogleTest)
|
||||
add_executable(vbt_test vbt_test.cpp)
|
||||
|
||||
target_link_libraries(
|
||||
vbt_test
|
||||
gtest
|
||||
gtest_main
|
||||
pthread
|
||||
)
|
||||
|
||||
add_test(vbt_test vbt_test)
|
9
gtest/vbt_test.cpp
Normal file
9
gtest/vbt_test.cpp
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
#include <gtest/gtest.h>
|
||||
#include "vbt/vbt.hpp"
|
||||
|
||||
|
||||
TEST(vbt_test, put) {
|
||||
VBTree<int, int> vbt;
|
||||
vbt.put(0, 0);
|
||||
}
|
5
src/main.cpp
Normal file
5
src/main.cpp
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include <iostream>
|
||||
|
||||
int main(int, char**) {
|
||||
std::cout << "Hello, world!\n";
|
||||
}
|
21
src/vbt/compare.hpp
Normal file
21
src/vbt/compare.hpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef __COMPARE__
|
||||
#define __COMPARE__
|
||||
|
||||
template<class T>
|
||||
int compare(T v1, T v2)
|
||||
{
|
||||
if (v1 > v2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (v1 < v2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __COMPARE__
|
341
src/vbt/vbt.hpp
Normal file
341
src/vbt/vbt.hpp
Normal file
|
@ -0,0 +1,341 @@
|
|||
|
||||
#ifndef __VBTREE__
|
||||
#define __VBTREE__
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include "compare.hpp"
|
||||
|
||||
using namespace std;
|
||||
using std::cout, std::endl;
|
||||
using std::tuple, std::make_tuple;
|
||||
|
||||
typedef unsigned long ULONG;
|
||||
|
||||
template <class TKey, class TValue, int Compare(TKey, TKey) = compare>
|
||||
class VBTree
|
||||
{
|
||||
public:
|
||||
enum CHILDREN {LEFT = 0, RIGHT = 1};
|
||||
public:
|
||||
struct TreeNode
|
||||
{
|
||||
TreeNode *children[2];
|
||||
TreeNode *parent;
|
||||
unsigned long size;
|
||||
TKey key;
|
||||
TValue value;
|
||||
|
||||
TreeNode()
|
||||
{
|
||||
this->children[LEFT] = NULL;
|
||||
this->children[RIGHT] = NULL;
|
||||
this->parent = NULL;
|
||||
this->size = 1;
|
||||
}
|
||||
/* data */
|
||||
};
|
||||
|
||||
private:
|
||||
TreeNode *root;
|
||||
inline ULONG get_size(TreeNode *cur)
|
||||
{
|
||||
if (cur == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return cur->size;
|
||||
}
|
||||
|
||||
inline ULONG get_children_sum_size(TreeNode *cur)
|
||||
{
|
||||
return this->get_size(cur->children[LEFT]) + this->get_size(cur->children[RIGHT]);
|
||||
}
|
||||
|
||||
inline tuple<ULONG, ULONG> get_children_size(TreeNode *cur)
|
||||
{
|
||||
return make_tuple(this->get_size(cur->children[LEFT]), this->get_size(cur->children[RIGHT]));
|
||||
}
|
||||
|
||||
inline void swap_keyvalue(TreeNode *n1, TreeNode *n2)
|
||||
{
|
||||
TKey tempkey = n1->key;
|
||||
TValue tempvalue = n1->value;
|
||||
|
||||
n1->key = n2->key; //交换值达到, 相对位移
|
||||
n1->value = n2->value;
|
||||
|
||||
n2->key = tempkey;
|
||||
n2->value = tempvalue;
|
||||
}
|
||||
|
||||
template<int left, int right>
|
||||
inline void xxrotate3(TreeNode *cur) { //
|
||||
TreeNode *movparent = cur->children[left];
|
||||
TreeNode *mov = movparent->children[right];
|
||||
|
||||
this->swap_keyvalue(mov, cur);
|
||||
|
||||
cur->children[right] = mov;
|
||||
mov->parent = cur;
|
||||
|
||||
cur->children[left] = movparent;
|
||||
movparent->children[right] = NULL;
|
||||
|
||||
cur->children[right] = mov;
|
||||
mov->parent = cur;
|
||||
|
||||
cur->children[left]->size = 1;
|
||||
}
|
||||
|
||||
template<int left, int right>
|
||||
inline void xxrotate(TreeNode *cur) {
|
||||
TreeNode *movparent = cur->children[left];
|
||||
TreeNode *mov = movparent->children[right];
|
||||
|
||||
this->swap_keyvalue(mov, cur);
|
||||
|
||||
if (mov->children[left] != NULL)
|
||||
{
|
||||
movparent->children[right] = mov->children[left];
|
||||
movparent->children[right]->parent = movparent;
|
||||
}
|
||||
else
|
||||
{
|
||||
movparent->children[right] = NULL;
|
||||
}
|
||||
|
||||
if (mov->children[right] != NULL)
|
||||
{
|
||||
mov->children[left] = mov->children[right];
|
||||
}
|
||||
else
|
||||
{
|
||||
mov->children[left] = NULL;
|
||||
}
|
||||
|
||||
if (cur->children[right] != NULL)
|
||||
{
|
||||
mov->children[right] = cur->children[right];
|
||||
mov->children[right]->parent = mov;
|
||||
}
|
||||
else
|
||||
{
|
||||
mov->children[right] = NULL;
|
||||
}
|
||||
|
||||
cur->children[right] = mov;
|
||||
mov->parent = cur;
|
||||
|
||||
movparent->size = this->get_children_sum_size(movparent) + 1;
|
||||
mov->size = this->get_children_sum_size(mov) + 1;
|
||||
cur->size = this->get_children_sum_size(cur) + 1;
|
||||
}
|
||||
|
||||
template<int left, int right>
|
||||
inline void xrotate3(TreeNode *cur) {
|
||||
TreeNode *mov = cur->children[left];
|
||||
|
||||
this->swap_keyvalue(mov, cur);
|
||||
|
||||
cur->children[right] = mov;
|
||||
|
||||
cur->children[left] = mov->children[left];
|
||||
cur->children[left]->parent = cur;
|
||||
|
||||
mov->children[left] = NULL;
|
||||
|
||||
mov->size = 1;
|
||||
}
|
||||
|
||||
template<int left, int right>
|
||||
inline void xrotate(TreeNode *cur) {
|
||||
// 1 right 0 left
|
||||
TreeNode *mov = cur->children[left];
|
||||
|
||||
this->swap_keyvalue(mov, cur);
|
||||
|
||||
// mov->children[l]不可能为nil
|
||||
mov->children[left]->parent = cur;
|
||||
|
||||
cur->children[left] = mov->children[left];
|
||||
|
||||
// 解决mov节点孩子转移的问题
|
||||
if (mov->children[right] != NULL)
|
||||
{
|
||||
mov->children[left] = mov->children[right];
|
||||
}
|
||||
else
|
||||
{
|
||||
mov->children[left] = NULL;
|
||||
}
|
||||
|
||||
if (cur->children[right] != NULL)
|
||||
{
|
||||
mov->children[right] = cur->children[right];
|
||||
mov->children[right]->parent = mov;
|
||||
}
|
||||
else
|
||||
{
|
||||
mov->children[right] = NULL;
|
||||
}
|
||||
|
||||
// 连接转移后的节点 由于mov只是与cur交换值,parent不变
|
||||
cur->children[right] = mov;
|
||||
|
||||
mov->size = get_children_sum_size(mov) + 1;
|
||||
cur->size = get_children_sum_size(cur) + 1;
|
||||
}
|
||||
|
||||
inline void fix_size(TreeNode *cur, ULONG ls, ULONG rs)
|
||||
{
|
||||
if (ls > rs)
|
||||
{
|
||||
tuple<ULONG, ULONG> lllr = this->get_children_size(cur->children[LEFT]);
|
||||
ULONG llsize = std::get<LEFT>(lllr);
|
||||
ULONG lrsize = std::get<RIGHT>(lllr);
|
||||
if (lrsize > llsize)
|
||||
{
|
||||
this->xxrotate<LEFT, RIGHT>(cur);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->xrotate<LEFT, RIGHT>(cur);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tuple<ULONG, ULONG> rlrr = this->get_children_size(cur->children[RIGHT]);
|
||||
ULONG rlsize = std::get<LEFT>(rlrr);
|
||||
ULONG rrsize = std::get<RIGHT>(rlrr);
|
||||
if (rlsize > rrsize)
|
||||
{
|
||||
this->xxrotate<RIGHT, LEFT>(cur);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->xrotate<RIGHT, LEFT>(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
VBTree()
|
||||
{
|
||||
this->root = NULL;
|
||||
}
|
||||
|
||||
TValue* get(TKey key)
|
||||
{
|
||||
for (TreeNode *n = this->root; n != NULL;)
|
||||
{
|
||||
int c = Compare(key, n->key);
|
||||
switch (c)
|
||||
{
|
||||
case -1:
|
||||
n = n->children[LEFT];
|
||||
break;
|
||||
case 1:
|
||||
n = n->children[RIGHT];
|
||||
break;
|
||||
case 0:
|
||||
return &n->value;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void put(TKey key, TValue value)
|
||||
{
|
||||
|
||||
if (this->root == NULL)
|
||||
{
|
||||
TreeNode *node = new TreeNode();
|
||||
node->key = key;
|
||||
node->value = value;
|
||||
this->root = node;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (TreeNode *cur = this->root;;)
|
||||
{
|
||||
if (cur->size > 8)
|
||||
{
|
||||
unsigned long factor = cur->size >> 3; // 原来是/10 为了简化为位运算/8
|
||||
unsigned long ls = cur->children[LEFT]->size;
|
||||
unsigned long rs = cur->children[RIGHT]->size;
|
||||
if (rs >= (ls << 1) + factor || ls >= (rs << 1) + factor) // ls rs * 2
|
||||
{
|
||||
this->fix_size(cur, ls, rs);
|
||||
}
|
||||
}
|
||||
|
||||
cur->size++;
|
||||
|
||||
int c = Compare(key, cur->key);
|
||||
if (c < 0)
|
||||
{
|
||||
if (cur->children[LEFT] == NULL)
|
||||
{
|
||||
TreeNode *node = new TreeNode();
|
||||
node->key = key;
|
||||
node->value = value;
|
||||
|
||||
cur->children[LEFT] = node;
|
||||
node->parent = cur;
|
||||
|
||||
if (cur->parent != NULL && cur->parent->size == 3)
|
||||
{
|
||||
if (cur->parent->children[LEFT] == NULL)
|
||||
{
|
||||
this->xxrotate3<RIGHT, LEFT>(cur->parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->xrotate3<LEFT, RIGHT>(cur->parent);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
cur = cur->children[LEFT];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cur->children[RIGHT] == NULL)
|
||||
{
|
||||
TreeNode *node = new TreeNode();
|
||||
node->key = key;
|
||||
node->value = value;
|
||||
|
||||
cur->children[RIGHT] = node;
|
||||
node->parent = cur;
|
||||
|
||||
if (cur->parent != NULL && cur->parent->size == 3)
|
||||
{
|
||||
if (cur->parent->children[RIGHT] == NULL)
|
||||
{
|
||||
this->xxrotate3<LEFT, RIGHT>(cur->parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->xrotate3<RIGHT, LEFT>(cur->parent);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
cur = cur->children[RIGHT];
|
||||
}
|
||||
}
|
||||
|
||||
cout << "error" << endl;
|
||||
return ;
|
||||
};
|
||||
|
||||
/* data */
|
||||
};
|
||||
|
||||
|
||||
#endif // __VBTREE__
|
Loading…
Reference in New Issue
Block a user