C語言 2-3樹
阿新 • • 發佈:2018-12-25
2-3樹簡介
2-3樹是最簡單的B-樹(或-樹)結構,其每個非葉節點都有兩個或三個子女,而且所有葉都在統一層上。
實現過程
在2-3樹中,一個結點只有一個值的我們稱為2-結點,有兩個值的稱為3-結點,在2-3樹中,一個結點最多隻有兩個值,即3-結點。
什麼時候我們認為2-3樹不平衡呢?就是任意一個結點到最後每個結點的距離都相等。
當結點變成4-結點的時候,總共會有6種情況:
所以針對每一種情況,我們一一實現就可以實現2-3樹了。
程式碼實現
ADT :
typedef struct node {
int a[3]; //a[2],作為4-結點時的快取
int num; //陣列a的長度:1,2,3
struct node *left_child;
struct node *mid_child;
struct node *right_child;
struct node *tmp_child; //作為4-結點時的快取
struct node *parent;
} Btree, *BtreePtr;
void exchange(int *a, int *b);
BtreePtr _node(const int key); //create a node
void _sort(BtreePtr b); //sort a[]
BtreePtr _checkNum(BtreePtr p); //balance
BtreePtr _insertBTree(BtreePtr b, const int key, const int pos); //insert key
BtreePtr insertBTree(BtreePtr root, const int key, const int pos); //initial
void freeTree(BtreePtr p);
int BTreeSearch(const int *a, const int length, const int key) ;
完整程式碼:
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#define NUM(p) ((p==NULL)?0:p->num)
typedef struct node {
int a[3];
int num; //1,2,3
struct node *left_child;
struct node *mid_child;
struct node *right_child;
struct node *tmp_child;
struct node *parent;
} Btree, *BtreePtr;
void exchange(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
BtreePtr _node(const int key) {
BtreePtr p = (BtreePtr)malloc(sizeof(Btree));
if (p != NULL) {
memset(p, 0, sizeof(p));
p->a[0] = key;
p->num = 1;
p->left_child = NULL;
p->right_child = NULL;
p->mid_child = NULL;
p->tmp_child = NULL;
p->parent = NULL;
}
else {
puts("記憶體不足");
}
return p;
}
void _sort(BtreePtr b) {
int length = b->num;
for (int i = 0; i < length; i++) {
for (int j = i; j < length; j++) {
if ((b->a[j]) < (b->a[i])) {
exchange(&(b->a[j]), &(b->a[i]));
}
}
}
}
BtreePtr _checkNum(BtreePtr p) {
if (NUM(p) == 1) { //2-結點
if (NUM(p->left_child) == 3) { //case 2
p->a[1] = p->left_child->a[1];
p->num++;
_sort(p);
BtreePtr l = _node(p->left_child->a[0]);
l->left_child = p->left_child->left_child;
l->parent = p;
BtreePtr r = _node(p->left_child->a[2]);
r->left_child = p->left_child->mid_child;
r->right_child = p->left_child->right_child;
r->parent = p;
p->left_child = l;
p->mid_child = r;
}
else if (NUM(p->right_child) == 3) { //case 3
p->a[1] = p->right_child->a[1];
p->num++;
_sort(p);
BtreePtr l = _node(p->right_child->a[0]);
l->left_child = p->right_child->left_child;
l->parent = p;
BtreePtr r = _node(p->right_child->a[2]);
r->left_child = p->right_child->mid_child;
r->right_child = p->right_child->right_child;
r->parent = p;
p->mid_child = l;
p->right_child = r;
}
}
else if (NUM(p) == 2) { //3-結點
if (NUM(p->left_child) == 3) { //case 4
p->a[2] = p->left_child->a[1];
p->num++;
_sort(p);
p->tmp_child = p->mid_child;
p->mid_child = _node(p->left_child->a[2]);
BtreePtr l = _node(p->left_child->a[0]);
l->left_child = p->left_child->left_child;
l->right_child = p->left_child->mid_child;
l->parent = p;
BtreePtr r = _node(p->left_child->a[2]);
r->left_child = p->left_child->tmp_child;
r->right_child = p->left_child->right_child;
r->parent = p;
p->left_child = l;
}
else if (NUM(p->right_child) == 3) { //case 5
p->a[2] = p->right_child->a[1];
p->num++;
_sort(p);
p->tmp_child = _node(p->right_child->a[2]); //
BtreePtr l = _node(p->right_child->a[0]);
l->right_child = p->right_child->left_child;
l->right_child = p->right_child->mid_child;
l->parent = p;
BtreePtr r = _node(p->right_child->a[2]);
r->right_child = p->right_child->tmp_child;
r->right_child = p->right_child->right_child;
r->parent = p;
p->right_child = l;
}
else if (NUM(p->mid_child) == 3) {
p->a[2] = p->mid_child->a[1];
p->num++;
_sort(p);
//p->tmp_child = p->mid_child;
//p->mid_child = _node(p->left_child->a[2]);
BtreePtr l = _node(p->mid_child->a[0]);
l->left_child = p->mid_child->left_child;
l->right_child = p->mid_child->mid_child;
l->parent = p;
BtreePtr r = _node(p->mid_child->a[2]);
r->left_child = p->mid_child->tmp_child;
r->right_child = p->mid_child->right_child;
r->parent = p;
p->mid_child = l;
p->tmp_child = r;
}
}
if (p->num == 3) {
if (p->parent == NULL) { // case 1;
BtreePtr t = p->left_child;
p->left_child = _node(p->a[0]);
p->left_child->left_child = t;
p->left_child->right_child = p->mid_child;
p->left_child->parent = p;
t = p->right_child;
p->right_child = _node(p->a[2]);
p->right_child->left_child = p->tmp_child;
p->right_child->right_child = t;
p->right_child->parent = p;
p->mid_child = NULL;
p->tmp_child = NULL;
p->a[0] = p->a[1];
p->num = p->num - 2;
}
}
return p;
}
BtreePtr _insertBTree(BtreePtr b, const int key, const int pos) {
if (b->left_child == NULL && b->right_child == NULL) { //底節點
b->a[b->num] = key;
b->num++;
_sort(b);
}
else {
if (b->num == 1) {
if (key < b->a[0]) { //num =1, 2
b->left_child = _insertBTree(b->left_child, key, pos);
}
else if (key > b->a[0]) { //num = 2
b->right_child = _insertBTree(b->right_child, key, pos);
}
}
else if (b->num == 2) {
if (key < b->a[0]) { //num =1, 2
b->left_child = _insertBTree(b->left_child, key, pos);
}
else if (key > b->a[1]) { //num = 2
b->right_child = _insertBTree(b->right_child, key, pos);
}
else {
b->mid_child = _insertBTree(b->mid_child, key, pos);
}
}
}
b = _checkNum(b);
return b;
}
BtreePtr insertBTree(BtreePtr root, const int key, const int pos) {
if (root == NULL) {
root = _node(key);
}
else {
root = _insertBTree(root, key, pos);
}
return root;
}
void freeTree(BtreePtr p) {
if (p->left_child != NULL) {
freeTree(p->left_child);
}
if (p->right_child != NULL) {
freeTree(p->right_child);
}
if (p->mid_child != NULL) {
freeTree(p->mid_child);
}
free(p);
p = NULL;
}
int BTreeSearch(const int *a, const int length, const int key) {
BtreePtr root = NULL;
for (int i = 0; i < length; i++) {
root = insertBTree(root, a[i], i);
}
freeTree(root);
return -1;
}
void main() {
const int length = 8;
int my_array[8] = { 7, 5, 9 ,11,10,6, 12, 13};
BTreeSearch(my_array, length, 7);
}