# define _CRT_SECURE_NO_WARNINGS
# pragma warning ( disable: 6031 )
# include <stdio.h>
# include <stdlib.h>
# include <bits/stdc++.h>
using namespace std;
# define m 3
# define minn ( m + 1 ) / 2 - 1
typedef struct BTNode
{ int key[ m + 1 ] ; struct BTNode * ptr[ m + 1 ] ; int keynum; struct BTNode * parent;
} BTNode, * BTree;
typedef struct
{ BTNode* pt; int i; bool tag;
} Result;
void Restore ( BTree& t, BTree& p) ;
void Merge ( BTree& l, BTree& parent, BTree& r, BTree& t, int i) ;
int Search ( BTNode* cur, int key)
{ int i = 1 ; while ( i <= cur-> keynum && key > cur-> key[ i] ) { i++ ; } return i;
}
void SearchBTree ( BTree t, int key, Result & r)
{ BTNode* cur = t; BTNode* pre = NULL ; bool flag = false ; int i = 0 ; while ( cur != NULL && flag == false ) { i = Search ( cur, key) ; if ( i <= cur-> keynum && key == cur-> key[ i] ) { flag = true ; } else { pre = cur; cur = cur-> ptr[ i - 1 ] ; } } if ( flag == true ) { r. pt = cur; r. i = i; r. tag = true ; } else { r. pt = pre; r. i = i; r. tag = false ; }
}
void printBTree ( BTree t, int num)
{ if ( t == NULL ) { return ; } int i = 0 ; for ( i = 1 ; i <= num; i++ ) { cout << "\t" ; } for ( i = 1 ; i <= t-> keynum; i++ ) { cout << t-> key[ i] << " " ; } cout << endl; for ( i = 0 ; i <= t-> keynum; i++ ) { printBTree ( t-> ptr[ i] , num + 1 ) ; }
}
void newRoot ( BTree& t, BTNode* p, int key, BTNode* ap)
{ t = ( BTNode* ) malloc ( sizeof ( BTNode) ) ; if ( t != NULL ) { t-> keynum = 1 ; t-> key[ 1 ] = key; t-> ptr[ 0 ] = p; t-> ptr[ 1 ] = ap; if ( p != NULL ) { p-> parent = t; } if ( ap != NULL ) { ap-> parent = t; } t-> parent = NULL ; }
}
void Insert ( BTree& q, int i, int key, BTNode* ap)
{ int n = q-> keynum; for ( int j = n; j >= i; j-- ) { q-> key[ j + 1 ] = q-> key[ j] ; q-> ptr[ j + 1 ] = q-> ptr[ j] ; } q-> key[ i] = key; q-> ptr[ i] = ap; if ( ap != NULL ) { ap-> parent = q; } q-> keynum++ ;
}
void split ( BTree& q, int s, BTree& ap)
{ int n = q-> keynum; ap = ( BTNode* ) malloc ( sizeof ( BTNode) ) ; if ( ap != NULL ) { ap-> ptr[ 0 ] = q-> ptr[ s] ; for ( int i = s + 1 , j = 1 ; i <= n; i++ , j++ ) { ap-> key[ j] = q-> key[ i] ; ap-> ptr[ j] = q-> ptr[ i] ; } ap-> keynum = n - s; ap-> parent = q-> parent; q-> keynum = s - 1 ; for ( int i = 0 ; i <= ap-> keynum; i++ ) { if ( ap-> ptr[ i] != NULL ) { ap-> ptr[ i] -> parent = ap; } } }
}
void InsertBtree ( BTree& t, int key, BTNode* q, int i)
{ int x = key; int s; BTNode* ap = NULL ; if ( q == NULL ) { newRoot ( t, NULL , key, NULL ) ; return ; } bool needNewRoot = false ; bool finish = false ; while ( needNewRoot == false && finish == false ) { Insert ( q, i, x, ap) ; if ( q-> keynum < m) { finish = true ; } else { s = ( m + 1 ) / 2 ; split ( q, s, ap) ; x = q-> key[ s] ; if ( q-> parent != NULL ) { q = q-> parent; i = Search ( q, x) ; } else { needNewRoot = true ; } } } if ( needNewRoot == true ) { newRoot ( t, q, x, ap) ; }
}
void insertKeyOperater ( BTree& t)
{ int key = 0 ; Result r; while ( 1 ) { cout << "请输入想要插入的关键字:" << endl; cin >> key; SearchBTree ( t, key, r) ; if ( r. tag == true ) { cout << "B树中已存在Key为:" << key << "的节点,插入失败!" << endl; } else { InsertBtree ( t, key, r. pt, r. i) ; cout << "插入成功!" << endl; cout << "插入后的B树如下:" << endl; printBTree ( t, 1 ) ; } cout << "是否继续新插入?(y/n)" << endl; char c; cin >> c; cout << endl; if ( c == 'n' || c == 'N' ) { break ; } }
}
void Merge ( BTree& l, BTree& parent, BTree& r, BTree& t, int i)
{ l-> key[ l-> keynum + 1 ] = parent-> key[ i] ; l-> ptr[ l-> keynum + 1 ] = r-> ptr[ 0 ] ; if ( l-> ptr[ l-> keynum + 1 ] != NULL ) { l-> ptr[ l-> keynum + 1 ] -> parent = l; } ++ l-> keynum; for ( int j = 1 ; j <= r-> keynum; j++ ) { l-> key[ l-> keynum + j] = r-> key[ j] ; l-> ptr[ l-> keynum + j] = r-> ptr[ j] ; if ( l-> ptr[ l-> keynum + j] != NULL ) { l-> ptr[ l-> keynum + j] -> parent = l; } ++ l-> keynum; } parent-> ptr[ i] = NULL ; free ( r) ; r = NULL ; for ( int j = i; j < parent-> keynum; j++ ) { parent-> key[ j] = parent-> key[ j + 1 ] ; parent-> ptr[ j] = parent-> ptr[ j + 1 ] ; } -- parent-> keynum; if ( parent == t) { if ( parent-> keynum == 0 ) { for ( int j = 0 ; j <= parent-> keynum + 1 ; j++ ) { if ( parent-> ptr[ j] != NULL ) { t = parent-> ptr[ j] ; t-> parent = NULL ; break ; } } } } else { if ( parent-> keynum < minn) { Restore ( t, parent) ; } }
}
void Borrow ( BTree& p, BTree& lbro, BTree& rbro, BTree& parent, int i)
{ if ( lbro != NULL && lbro-> keynum > minn) { for ( int j = p-> keynum + 1 ; j > 0 ; j-- ) { if ( j > 1 ) { p-> key[ j] = p-> key[ j - 1 ] ; } p-> ptr[ j] = p-> ptr[ j - 1 ] ; } p-> key[ 1 ] = parent-> key[ i] ; parent-> key[ i] = lbro-> key[ lbro-> keynum] ; p-> ptr[ 0 ] = lbro-> ptr[ lbro-> keynum] ; if ( p-> ptr[ 0 ] != NULL ) { p-> ptr[ 0 ] -> parent = p; } lbro-> ptr[ lbro-> keynum] = NULL ; ++ p-> keynum; -- lbro-> keynum; } else { p-> key[ p-> keynum + 1 ] = parent-> key[ i + 1 ] ; parent-> key[ i + 1 ] = rbro-> key[ 1 ] ; p-> ptr[ p-> keynum + 1 ] = rbro-> ptr[ 0 ] ; if ( p-> ptr[ p-> keynum + 1 ] != NULL ) { p-> ptr[ p-> keynum + 1 ] -> parent = p; } for ( int j = 0 ; j < rbro-> keynum; j++ ) { if ( j > 0 ) { rbro-> key[ j] = rbro-> key[ j + 1 ] ; } rbro-> ptr[ j] = rbro-> ptr[ j + 1 ] ; } rbro-> ptr[ rbro-> keynum] = NULL ; ++ p-> keynum; -- rbro-> keynum; }
}
void Restore ( BTree& t, BTree& p)
{ BTree parent = p-> parent, lbro = NULL , rbro = NULL ; int i = 0 ; for ( i = 0 ; i <= parent-> keynum; i++ ) { if ( parent-> ptr[ i] == p) { break ; } } if ( i > 0 ) { lbro = parent-> ptr[ i - 1 ] ; } if ( i < parent-> keynum) { rbro = parent-> ptr[ i + 1 ] ; } if ( ( lbro != NULL && lbro-> keynum > minn) || ( rbro != NULL && rbro-> keynum > minn) ) { Borrow ( p, lbro, rbro, parent, i) ; } else { if ( lbro != NULL ) { Merge ( lbro, parent, p, t, i) ; } else if ( rbro != NULL ) { Merge ( p, parent, rbro, t, i + 1 ) ; } }
}
void Remove ( BTree& p, int i)
{ int j = i; for ( j = i; j < p-> keynum; j++ ) { p-> key[ j] = p-> key[ j + 1 ] ; p-> ptr[ j] = p-> ptr[ j + 1 ] ; } -- p-> keynum;
}
void Successor ( BTree& p, int i)
{ BTree leaf = p; if ( p == NULL ) { return ; } leaf = p-> ptr[ i] ; while ( leaf-> ptr[ 0 ] != NULL ) { leaf = leaf-> ptr[ 0 ] ; } p-> key[ i] = leaf-> key[ 1 ] ; p = leaf;
}
void DeleteBTree ( BTree& t, BTree& p, int i)
{ if ( p-> ptr[ i] != NULL ) { Successor ( p, i) ; i = 1 ; } Remove ( p, i) ; if ( p-> parent == NULL && p-> keynum == 0 ) { t = NULL ; } if ( p-> parent != NULL && p-> keynum < minn) { Restore ( t, p) ; }
}
void deleteKeyOperater ( BTree& t)
{ Result r; int key = 0 ; while ( 1 ) { cout << "请输入想要删除的关键字:" << endl; cin >> key; SearchBTree ( t, key, r) ; if ( r. tag == true ) { DeleteBTree ( t, r. pt, r. i) ; cout << "删除成功!" << endl; cout << "删除后的B树如下:" << endl; printBTree ( t, 1 ) ; } else { cout << "B树中不存在Key为:" << key << "的节点,删除失败!" << endl; break ; } }
} int main ( )
{ BTree t = NULL ; insertKeyOperater ( t) ; deleteKeyOperater ( t) ; return 0 ;
}