B树算法与实现 (C语言实现)
B树的定义
假设B树的度为t(t>=2),则B树满足如下要求:(参考算法导论)
(1) 每个非根节点至少包含t-1个关键字,t个指向子节点的指针;至多包含2t-1个关键字,2t个指向子女的指针(叶子节点的子女为空)。
(2) 节点的所有key按非降序存放,假设节点的关键字分别为K[1], K[2] … K[n], 指向子女的指针分别为P[1], P[2]…P[n+1],其中n为节点关键字的个数。则有:
P[1] <= K[1] <= P[2] <= K[2] …..<= K[n] <= P[n+1] // 这里P[n]也指其指向的关键字
(3) 若根节点非空,则根节点至少包含两个子女;
(4) 所有的叶子节点都在同一层。
B树的搜索,search(root, target)
从root出发,对每个节点,找到大于或等于target关键字中最小的K[i],如果K[i]与target相等,则查找成功;否则在P[i]中递归搜索target,直到到达叶子节点,如仍未找到则说明关键字不在B树中,查找失败。
B树的插入,insert(root, target)
B树的插入需要沿着搜索的路径从root一直到叶节点,根据B树的规则,每个节点的关键字个数在[t-1, 2t-1]之间,故当target要加入到某个叶子时,如果该叶子节点已经有2t-1个关键字,则再加入target就违反了B树的定义,这时就需要对该叶子节点进行分裂,将叶子以中间节点为界,分成两个包含t-1个关键字的子节点,同时把中间节点提升到该叶子的父节点中,如果这样使得父节点的关键字个数超过2t-1,则要继续向上分裂,直到根节点,根节点的分裂会使得树加高一层。
上面的过程需要回溯,那么能否从根下降到叶节点后不回溯就能完成节点的插入呢?答案是肯定的,核心思想就是未雨绸缪,在下降的过程中,一旦遇到已满的节点(关键字个数为2t-1),就就对该节点进行分裂,这样就保证在叶子节点需要分裂时,其父节点一定是非满的,从而不需要再向上回溯。
B树的删除,delete(root, target)
在删除B树节点时,为了避免回溯,当遇到需要合并的节点时就立即执行合并,B树的删除算法如下:从root向叶子节点按照search规律遍历:
(1) 如果target在叶节点x中,则直接从x中删除target,情况(2)和(3)会保证当再叶子节点找到target时,肯定能借节点或合并成功而不会引起父节点的关键字个数少于t-1。
(2) 如果target在分支节点x中:
(a) 如果x的左分支节点y至少包含t个关键字,则找出y的最右的关键字prev,并替换target,并在y中递归删除prev。
(b) 如果x的右分支节点z至少包含t个关键字,则找出z的最左的关键字next,并替换target,并在z中递归删除next。
(c) 否则,如果y和z都只有t-1个关键字,则将targe与z合并到y中,使得y有2t-1个关键字,再从y中递归删除target。
(3) 如果关键字不在分支节点x中,则必然在x的某个分支节点p[i]中,如果p[i]节点只有t-1个关键字。
(a) 如果p[i-1]拥有至少t个关键字,则将x的某个关键字降至p[i]中,将p[i-1]的最大节点上升至x中。
(b) 如果p[i+1]拥有至少t个关键字,则将x个某个关键字降至p[i]中,将p[i+1]的最小关键字上升至x个。
(c) 如果p[i-1]与p[i+1]都拥有t-1个关键字,则将p[i]与其中一个兄弟合并,将x的一个关键字降至合并的节点中,成为中间关键字。
btree.c
#include <stdio.h>
#include <stdlib.h>
/**
* @brief the degree of btree
* key per node: [M-1, 2M-1]
* child per node: [M, 2M]
*/
#define M 2
typedef struct btree_node {
*M-];
*M];
int num;
bool is_leaf;
} btree_node;
/**
* @brief allocate a new btree node
* default: is_leaf == true
*
* @return pointer of new node
*/
btree_node *btree_node_new();
/**
* @brief create a btree root
*
* @return pointer of btree root
*/
btree_node *btree_create();
/**
* @brief split child if num of key in child exceed 2M-1
*
* @param parent: parent of child
* @param pos: p[pos] points to child
* @param child: the node to be splited
*
* @return
*/
int btree_split_child(btree_node *parent, int pos, btree_node *child);
/**
* @brief insert a value into btree
* the num of key in node less than 2M-1
*
* @param node: tree root
* @param target: target to insert
*/
void btree_insert_nonfull(btree_node *node, int target);
/**
* @brief insert a value into btree
*
* @param root: tree root
* @param target: target to insert
*
* @return: new root of tree
*/
btree_node* btree_insert(btree_node *root, int target);
/**
* @brief merge y, z and root->k[pos] to left
* this appens while y and z both have M-1 keys
*
* @param root: parent node
* @param pos: postion of y
* @param y: left node to merge
* @param z: right node to merge
*/
void btree_merge_child(btree_node *root, int pos, btree_node *y, btree_node *z);
/**
* @brief delete a vlue from btree
*
* @param root: btree root
* @param target: target to delete
*
* @return: new root of tree
*/
btree_node *btree_delete(btree_node *root, int target);
/**
* @brief delete a vlue from btree
* root has at least M keys
*
* @param root: btree root
* @param target: target to delete
*
* @return
*/
void btree_delete_nonone(btree_node *root, int target);
/**
* @brief find the rightmost value
*
* @param root: root of tree
*
* @return: the rightmost value
*/
int btree_search_predecessor(btree_node *root);
/**
* @brief find the leftmost value
*
* @param root: root of tree
*
* @return: the leftmost value
*/
int btree_search_successor(btree_node *root);
/**
* @brief shift a value from z to y
*
* @param root: btree root
* @param pos: position of y
* @param y: left node
* @param z: right node
*/
void btree_shift_to_left_child(btree_node *root, int pos, btree_node *y, btree_node *z);
/**
* @brief shift a value from z to y
*
* @param root: btree root
* @param pos: position of y
* @param y: left node
* @param z: right node
*/
void btree_shift_to_right_child(btree_node *root, int pos, btree_node *y, btree_node *z);
/**
* @brief inorder traverse the btree
*
* @param root: root of treee
*/
void btree_inorder_print(btree_node *root);
/**
* @brief level print the btree
*
* @param root: root of tree
*/
void btree_level_display(btree_node *root);
btree_node *btree_node_new()
{
btree_node *node = (btree_node *)malloc(sizeof(btree_node));
if(NULL == node) {
return NULL;
}
; i < * M -; i++) {
node->k[i] = ;
}
; i < * M; i++) {
node->p[i] = NULL;
}
node->num = ;
node->is_leaf = true;
}
btree_node *btree_create()
{
btree_node *node = btree_node_new();
if(NULL == node) {
return NULL;
}
return node;
}
int btree_split_child(btree_node *parent, int pos, btree_node *child)
{
btree_node *new_child = btree_node_new();
if(NULL == new_child) {
;
}
new_child->is_leaf = child->is_leaf;
new_child->num = M - ;
; i < M - ; i++) {
new_child->k[i] = child->k[i+M];
}
if(false == new_child->is_leaf) {
; i < M; i++) {
new_child->p[i] = child->p[i+M];
}
}
child->num = M - ;
for(int i = parent->num; i > pos; i--) {
parent->p[i+] = parent->p[i];
}
parent->p[pos+] = new_child;
; i >= pos; i--) {
parent->k[i+] = parent->k[i];
}
parent->k[pos] = child->k[M-];
parent->num += ;
}
void btree_insert_nonfull(btree_node *node, int target)
{
== node->is_leaf) {
int pos = node->num;
&& target < node->k[pos-]) {
node->k[pos] = node->k[pos-];
pos--;
}
node->k[pos] = target;
node->num += ;
} else {
int pos = node->num;
&& target < node->k[pos-]) {
pos--;
}
* M - == node->p[pos]->num) {
btree_split_child(node, pos, node->p[pos]);
if(target > node->k[pos]) {
pos++;
}
}
btree_insert_nonfull(node->p[pos], target);
}
}
btree_node* btree_insert(btree_node *root, int target)
{
if(NULL == root) {
return NULL;
}
* M - == root->num) {
btree_node *node = btree_node_new();
if(NULL == node) {
return root;
}
node->is_leaf = ;
node->p[] = root;
btree_split_child(node, , root);
btree_insert_nonfull(node, target);
return node;
} else {
btree_insert_nonfull(root, target);
return root;
}
}
void btree_merge_child(btree_node *root, int pos, btree_node *y, btree_node *z)
{
y->num = * M - ;
* M - ; i++) {
y->k[i] = z->k[i-M];
}
y->k[M-] = root->k[pos];
if(false == z->is_leaf) {
* M; i++) {
y->p[i] = z->p[i-M];
}
}
; j < root->num; j++) {
root->k[j-] = root->k[j];
root->p[j] = root->p[j+];
}
root->num -= ;
free(z);
}
btree_node *btree_delete(btree_node *root, int target)
{
== root->num) {
btree_node *y = root->p[];
btree_node *z = root->p[];
if(NULL != y && NULL != z &&
M - == y->num && M - == z->num) {
btree_merge_child(root, , y, z);
free(root);
btree_delete_nonone(y, target);
return y;
} else {
btree_delete_nonone(root, target);
return root;
}
} else {
btree_delete_nonone(root, target);
return root;
}
}
void btree_delete_nonone(btree_node *root, int target)
{
if(true == root->is_leaf) {
;
while(i < root->num && target > root->k[i]) i++;
if(target == root->k[i]) {
; j < * M - ; j++) {
root->k[j-] = root->k[j];
}
root->num -= ;
} else {
printf("target not found\n");
}
} else {
;
btree_node *y = NULL, *z = NULL;
while(i < root->num && target > root->k[i]) i++;
if(i < root->num && target == root->k[i]) {
y = root->p[i];
z = root->p[i+];
) {
int pre = btree_search_predecessor(y);
root->k[i] = pre;
btree_delete_nonone(y, pre);
} ) {
int next = btree_search_successor(z);
root->k[i] = next;
btree_delete_nonone(z, next);
} else {
btree_merge_child(root, i, y, z);
btree_delete(y, target);
}
} else {
y = root->p[i];
if(i < root->num) {
z = root->p[i+];
}
btree_node *p = NULL;
) {
p = root->p[i-];
}
) {
&& p->num > M - ) {
btree_shift_to_right_child(root, i-, p, y);
} ) {
btree_shift_to_left_child(root, i, y, z);
} ) {
btree_merge_child(root, i-, p, y); // note
y = p;
} else {
btree_merge_child(root, i, y, z);
}
btree_delete_nonone(y, target);
} else {
btree_delete_nonone(y, target);
}
}
}
}
int btree_search_predecessor(btree_node *root)
{
btree_node *y = root;
while(false == y->is_leaf) {
y = y->p[y->num];
}
];
}
int btree_search_successor(btree_node *root)
{
btree_node *z = root;
while(false == z->is_leaf) {
z = z->p[];
}
];
}
void btree_shift_to_right_child(btree_node *root, int pos,
btree_node *y, btree_node *z)
{
z->num += ;
; i > ; i--) {
z->k[i] = z->k[i-];
}
z->k[]= root->k[pos];
root->k[pos] = y->k[y->num-];
if(false == z->is_leaf) {
; i--) {
z->p[i] = z->p[i-];
}
z->p[] = y->p[y->num];
}
y->num -= ;
}
void btree_shift_to_left_child(btree_node *root, int pos,
btree_node *y, btree_node *z)
{
y->num += ;
y->k[y->num-] = root->k[pos];
root->k[pos] = z->k[];
; j < z->num; j++) {
z->k[j-] = z->k[j];
}
if(false == z->is_leaf) {
y->p[y->num] = z->p[];
; j <= z->num; j++) {
z->p[j-] = z->p[j];
}
}
z->num -= ;
}
void btree_inorder_print(btree_node *root)
{
if(NULL != root) {
btree_inorder_print(root->p[]);
; i < root->num; i++) {
printf("%d ", root->k[i]);
btree_inorder_print(root->p[i+]);
}
}
}
void btree_level_display(btree_node *root)
{
// just for simplicty, can't exceed 200 nodes in the tree
btree_node *queue[] = {NULL};
;
;
queue[rear++] = root;
while(front < rear) {
btree_node *node = queue[front++];
printf("[");
; i < node->num; i++) {
printf("%d ", node->k[i]);
}
printf("]");
; i <= node->num; i++) {
if(NULL != node->p[i]) {
queue[rear++] = node->p[i];
}
}
}
printf("\n");
}
int main()
{
, , , , , , , , , , , , };
btree_node *root = btree_create();
; i < sizeof(arr) / sizeof(int); i++) {
root = btree_insert(root, arr[i]);
btree_level_display(root);
}
//int todel[] = {15, 18, 23, 30, 31, 52, 50};
};
; i < sizeof(todel) / sizeof(int); i++) {
printf("after delete %d\n", todel[i]);
root = btree_delete(root, todel[i]);
btree_level_display(root);
}
;
}
B+树
与B树不同的时,B+树的关键字都存储在叶子节点,分支节点均为索引,在实现上大致与B树类似,在几个细节稍有不同。
(1) 数据结构中增加prev,next指针,用于将叶子节点串成有序双向链表。
(2) 在节点分裂的时候,如果分裂的节点为叶子,则需要把中间节点保留在左(或右)边的分支上,并且需要更新prev和next。
(3) 在节点合的时候,如果合并的节点为叶子,不需要把跟节点下降为中间节点,并且需要更新prev和next。
(4) 在向邻接节点借节点时,借来的关键字并不是父节点的关键字,而是邻接点的关键字,并根据实际情况更新父节点的索引。
bplustree.c
#include <stdio.h>
#include <stdlib.h>
/**
* @brief the degree of btree
* key per node: [M-1, 2M-1]
* child per node: [M, 2M]
*/
#define M 2 // the degree of btree
typedef struct btree_node {
*M-];
*M];
int num;
bool is_leaf;
struct btree_node *prev; // use one struct just for simple
struct btree_node *next;
} btree_node;
/**
* @brief allocate a new btree node
* default: is_leaf == true
*
* @return pointer of new node
*/
btree_node *btree_node_new();
/**
* @brief create a btree root
*
* @return pointer of btree root
*/
btree_node *btree_create();
/**
* @brief split child if num of key in child exceed 2M-1
*
* @param parent: parent of child
* @param pos: p[pos] points to child
* @param child: the node to be splited
*
* @return
*/
int btree_split_child(btree_node *parent, int pos, btree_node *child);
/**
* @brief insert a value into btree
* the num of key in node less than 2M-1
*
* @param node: tree root
* @param target: target to insert
*/
void btree_insert_nonfull(btree_node *node, int target);
/**
* @brief insert a value into btree
*
* @param root: tree root
* @param target: target to insert
*
* @return: new root of tree
*/
btree_node* btree_insert(btree_node *root, int target);
/**
* @brief merge y, z and root->k[pos] to left
* this appens while y and z both have M-1 keys
*
* @param root: parent node
* @param pos: postion of y
* @param y: left node to merge
* @param z: right node to merge
*/
void btree_merge_child(btree_node *root, int pos, btree_node *y, btree_node *z);
/**
* @brief delete a vlue from btree
*
* @param root: btree root
* @param target: target to delete
*
* @return: new root of tree
*/
btree_node *btree_delete(btree_node *root, int target);
/**
* @brief delete a vlue from btree
* root has at least M keys
*
* @param root: btree root
* @param target: target to delete
*
* @return
*/
void btree_delete_nonone(btree_node *root, int target);
/**
* @brief find the rightmost value
*
* @param root: root of tree
*
* @return: the rightmost value
*/
int btree_search_predecessor(btree_node *root);
/**
* @brief find the leftmost value
*
* @param root: root of tree
*
* @return: the leftmost value
*/
int btree_search_successor(btree_node *root);
/**
* @brief shift a value from z to y
*
* @param root: btree root
* @param pos: position of y
* @param y: left node
* @param z: right node
*/
void btree_shift_to_left_child(btree_node *root, int pos, btree_node *y, btree_node *z);
/**
* @brief shift a value from z to y
*
* @param root: btree root
* @param pos: position of y
* @param y: left node
* @param z: right node
*/
void btree_shift_to_right_child(btree_node *root, int pos, btree_node *y, btree_node *z);
/**
* @brief inorder traverse the btree
*
* @param root: root of treee
*/
void btree_inorder_print(btree_node *root);
/**
* @brief print tree linearly using prev/next pointer
*
* @param root: root of tree
*/
void btree_linear_print(btree_node *root);
/**
* @brief level print the btree
*
* @param root: root of tree
*/
void btree_level_display(btree_node *root);
btree_node *btree_node_new()
{
btree_node *node = (btree_node *)malloc(sizeof(btree_node));
if(NULL == node) {
return NULL;
}
; i < * M -; i++) {
node->k[i] = ;
}
; i < * M; i++) {
node->p[i] = NULL;
}
node->num = ;
node->is_leaf = true;
node->prev = NULL;
node->next = NULL;
}
btree_node *btree_create()
{
btree_node *node = btree_node_new();
if(NULL == node) {
return NULL;
}
node->next = node;
node->prev = node;
return node;
}
int btree_split_child(btree_node *parent, int pos, btree_node *child)
{
btree_node *new_child = btree_node_new();
if(NULL == new_child) {
;
}
new_child->is_leaf = child->is_leaf;
new_child->num = M - ;
; i < M - ; i++) {
new_child->k[i] = child->k[i+M];
}
if(false == new_child->is_leaf) {
; i < M; i++) {
new_child->p[i] = child->p[i+M];
}
}
child->num = M - ;
if(true == child->is_leaf) {
child->num++; // if leaf, keep the middle ele, put it in the left
}
for(int i = parent->num; i > pos; i--) {
parent->p[i+] = parent->p[i];
}
parent->p[pos+] = new_child;
; i >= pos; i--) {
parent->k[i+] = parent->k[i];
}
parent->k[pos] = child->k[M-];
parent->num += ;
// update link
if(true == child->is_leaf) {
new_child->next = child->next;
child->next->prev = new_child;
new_child->prev = child;
child->next = new_child;
}
}
void btree_insert_nonfull(btree_node *node, int target)
{
== node->is_leaf) {
int pos = node->num;
&& target < node->k[pos-]) {
node->k[pos] = node->k[pos-];
pos--;
}
node->k[pos] = target;
node->num += ;
} else {
int pos = node->num;
&& target < node->k[pos-]) {
pos--;
}
* M - == node->p[pos]->num) {
btree_split_child(node, pos, node->p[pos]);
if(target > node->k[pos]) {
pos++;
}
}
btree_insert_nonfull(node->p[pos], target);
}
}
btree_node* btree_insert(btree_node *root, int target)
{
if(NULL == root) {
return NULL;
}
* M - == root->num) {
btree_node *node = btree_node_new();
if(NULL == node) {
return root;
}
node->is_leaf = ;
node->p[] = root;
btree_split_child(node, , root);
btree_insert_nonfull(node, target);
return node;
} else {
btree_insert_nonfull(root, target);
return root;
}
}
void btree_merge_child(btree_node *root, int pos, btree_node *y, btree_node *z)
{
if(true == y->is_leaf) {
y->num = * M - ;
* M - ; i++) {
y->k[i-] = z->k[i-M];
}
} else {
y->num = * M - ;
* M - ; i++) {
y->k[i] = z->k[i-M];
}
y->k[M-] = root->k[pos];
* M; i++) {
y->p[i] = z->p[i-M];
}
}
; j < root->num; j++) {
root->k[j-] = root->k[j];
root->p[j] = root->p[j+];
}
root->num -= ;
// update link
if(true == y->is_leaf) {
y->next = z->next;
z->next->prev = y;
}
free(z);
}
btree_node *btree_delete(btree_node *root, int target)
{
== root->num) {
btree_node *y = root->p[];
btree_node *z = root->p[];
if(NULL != y && NULL != z &&
M - == y->num && M - == z->num) {
btree_merge_child(root, , y, z);
free(root);
btree_delete_nonone(y, target);
return y;
} else {
btree_delete_nonone(root, target);
return root;
}
} else {
btree_delete_nonone(root, target);
return root;
}
}
void btree_delete_nonone(btree_node *root, int target)
{
if(true == root->is_leaf) {
;
while(i < root->num && target > root->k[i]) i++;
if(target == root->k[i]) {
; j < * M - ; j++) {
root->k[j-] = root->k[j];
}
root->num -= ;
} else {
printf("target not found\n");
}
} else {
;
btree_node *y = NULL, *z = NULL;
while(i < root->num && target > root->k[i]) i++;
y = root->p[i];
if(i < root->num) {
z = root->p[i+];
}
btree_node *p = NULL;
) {
p = root->p[i-];
}
) {
&& p->num > M - ) {
btree_shift_to_right_child(root, i-, p, y);
} ) {
btree_shift_to_left_child(root, i, y, z);
} ) {
btree_merge_child(root, i-, p, y);
y = p;
} else {
btree_merge_child(root, i, y, z);
}
btree_delete_nonone(y, target);
} else {
btree_delete_nonone(y, target);
}
}
}
int btree_search_predecessor(btree_node *root)
{
btree_node *y = root;
while(false == y->is_leaf) {
y = y->p[y->num];
}
];
}
int btree_search_successor(btree_node *root)
{
btree_node *z = root;
while(false == z->is_leaf) {
z = z->p[];
}
];
}
void btree_shift_to_right_child(btree_node *root, int pos,
btree_node *y, btree_node *z)
{
z->num += ;
if(false == z->is_leaf) {
z->k[] = root->k[pos];
root->k[pos] = y->k[y->num-];
} else {
z->k[] = y->k[y->num-];
root->k[pos] = y->k[y->num-];
}
; i > ; i--) {
z->k[i] = z->k[i-];
}
if(false == z->is_leaf) {
; i--) {
z->p[i] = z->p[i-];
}
z->p[] = y->p[y->num];
}
y->num -= ;
}
void btree_shift_to_left_child(btree_node *root, int pos,
btree_node *y, btree_node *z)
{
y->num += ;
if(false == z->is_leaf) {
y->k[y->num-] = root->k[pos];
root->k[pos] = z->k[];
} else {
y->k[y->num-] = z->k[];
root->k[pos] = z->k[];
}
; j < z->num; j++) {
z->k[j-] = z->k[j];
}
if(false == z->is_leaf) {
y->p[y->num] = z->p[];
; j <= z->num; j++) {
z->p[j-] = z->p[j];
}
}
z->num -= ;
}
void btree_inorder_print(btree_node *root)
{
if(NULL != root) {
btree_inorder_print(root->p[]);
; i < root->num; i++) {
printf("%d ", root->k[i]);
btree_inorder_print(root->p[i+]);
}
}
}
void btree_linear_print(btree_node *root)
{
if(NULL != root) {
btree_node *leftmost = root;
while(false == leftmost->is_leaf) {
leftmost = leftmost->p[];
}
btree_node *iter = leftmost;
do {
; i < iter->num; i++) {
printf("%d ", iter->k[i]);
}
iter = iter->next;
} while(iter != leftmost);
printf("\n");
}
}
void btree_level_display(btree_node *root)
{
// just for simplicty, can't exceed 200 nodes in the tree
btree_node *queue[] = {NULL};
;
;
queue[rear++] = root;
while(front < rear) {
btree_node *node = queue[front++];
printf("[");
; i < node->num; i++) {
printf("%d ", node->k[i]);
}
printf("]");
; i <= node->num; i++) {
if(NULL != node->p[i]) {
queue[rear++] = node->p[i];
}
}
}
printf("\n");
}
int main()
{
, , , , , , , , , , , , };
// int arr[] = {18, 31, 12, 10};
btree_node *root = btree_create();
; i < sizeof(arr) / sizeof(int); i++) {
root = btree_insert(root, arr[i]);
btree_level_display(root);
btree_linear_print(root);
}
//int todel[] = {15, 18, 23, 30, 31, 52, 50};
, , , };
; i < sizeof(todel) / sizeof(int); i++) {
printf("after delete %d\n", todel[i]);
root = btree_delete(root, todel[i]);
btree_level_display(root);
btree_linear_print(root);
}
;
}
B树算法与实现 (C语言实现)的更多相关文章
- R语言 决策树算法
定义: 决策树(Decision Tree)是在已知各种情况发生概率的基础上,通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法,是直观运用概率分析的一种图解 ...
- 机器学习-决策树算法+代码实现(基于R语言)
分类树(决策树)是一种十分常用的分类方法.核心任务是把数据分类到可能的对应类别. 他是一种监管学习,所谓监管学习就是给定一堆样本,每个样本都有一组属性和一个类别,这些类别是事先确定的,通过学习得到一个 ...
- [转]机器学习——C4.5 决策树算法学习
1. 算法背景介绍 分类树(决策树)是一种十分常用的分类方法.它是一种监管学习,所谓监管学习说白了很简单,就是给定一堆样本,每个样本都有一组属性和一个类别,这些类别是事先确定的,那么通过学习得到一个分 ...
- 零基础数据分析与挖掘R语言实战课程(R语言)
随着大数据在各行业的落地生根和蓬勃发展,能从数据中挖金子的数据分析人员越来越宝贝,于是很多的程序员都想转行到数据分析, 挖掘技术哪家强?当然是R语言了,R语言的火热程度,从TIOBE上编程语言排名情况 ...
- 大数据时代的精准数据挖掘——使用R语言
老师简介: Gino老师,即将步入不惑之年,早年获得名校数学与应用数学专业学士和统计学专业硕士,有海外学习和工作的经历,近二十年来一直进行着数据分析的理论和实践,数学.统计和计算机功底强悍. 曾在某一 ...
- Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7)
http://blog.chinaunix.net/uid-20543672-id-3157283.html Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3 ...
- R语言进行机器学习方法及实例(一)
版权声明:本文为博主原创文章,转载请注明出处 机器学习的研究领域是发明计算机算法,把数据转变为智能行为.机器学习和数据挖掘的区别可能是机器学习侧重于执行一个已知的任务,而数据发掘是在大数据中寻找有 ...
- R语言︱XGBoost极端梯度上升以及forecastxgb(预测)+xgboost(回归)双案例解读
XGBoost不仅仅可以用来做分类还可以做时间序列方面的预测,而且已经有人做的很好,可以见最后的案例. 应用一:XGBoost用来做预测 ------------------------------- ...
- R语言︱决策树族——随机森林算法
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 笔者寄语:有一篇<有监督学习选择深度学习 ...
随机推荐
- 11.7---叠罗汉表演节目(CC150)
1,牛客网第一题:这其实跟找最长递增子序列是一个东西.注意的地方是,返回的是最大的dp,而不是dp[N-1]. 答案: public static int getHeight(int[] men, i ...
- git 使用入门篇
最近准备给同事培训git,发现了一个不错的资源,在这里:http://www.gitguys.com/topics/creating-a-shared-repository-users-sharing ...
- VC中基于 Windows 的精确定时[转]
在工业生产控制系统中,有许多需要定时完成的操作,如定时显示当前时间,定时刷新屏幕上的进度条,上位 机定时向下位机发送命令和传送数据等.特别是在对控制性能要求较高的实时控制系统和数据采集系统中,就更需要 ...
- 使用 PHP 7 给 Web 应用加速
PHP 20周年了!?? PHP 首发通告,1995年6月8日 发布于 COMP.INFOSYSTEMS.WWW.AUTHORING.CGI 主题:正式宣布:个人主页工具(Personal Home ...
- 怎样将myeclipse里默认编码设置成utf-8
需要设置三个位置: [1]需要在 Preferences->general->content types->下角是文件编码,可以自己定义 [2]windows->Prefer ...
- C#关于new的用法
1.运算符就是在实例化一个类的时候(运算符的用法) A a=new A(); 2.new 约束指定泛型类声明中的任何类型参数都必须有公共无参数构造函数.当泛型类创建类型的新实例时,将此约束应用于类型参 ...
- 51nod 1449 砝码称重(贪心算法)
题目:传送门. 题意:中文题. 题解:左物右码,w进制.m%w==0||m%w==1||m%w==w-1都是可以的,否则是NO. #include <iostream> #include ...
- 60. Permutation Sequence
题目: The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of t ...
- Mybatis 学习笔记1
---恢复内容开始--- 什么是 MyBatis ? MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获 ...
- Vi文档
Vi简介 Vi是一种广泛存在于各种UNIX和Linux系统中的文本编辑程序. Vi不是排版程序,只是一个纯粹的文本编辑程序. Vi是全屏幕文本编辑器,它没有菜单,只有命令. Vi不是基于窗口的,所以, ...