指路法定位结点
指路法通过根结点与目标结点的相对位置进行定位
在C语言中可以利用bit位进行指路
#define BT_LEFT 0
#define BT_RIGHT 1
二叉树存储结构简介
- 结点指针域定义
typedef struct _tag_BTreeNode BTreeNode;
struct _tag_BTreeNode
{
BTreeNode* left;
BTreeNode* right;
};
- 头结点定义
typedef struct _tag_BTree TBTree;
struct _tag_BTree
{
int count;
BTreeNode* root;
};
- 数据元素定义
struct Node
{
BTreeNode header;
char v;
};
代码实现
BTree.h
#pragma once
#define BT_LEFT 0
#define BT_RIGHT 1
typedef void BTree;
typedef unsigned long long BTPos;
typedef struct _tag_BTreeNode BTreeNode;
struct _tag_BTreeNode
{
BTreeNode* left;
BTreeNode* right;
};
typedef void (BTree_Printf)(BTreeNode*);
BTree* BTree_Create();
void BTree_Destroy(BTree* tree);
void BTree_Clear(BTree* tree);
int BTree_Insert(BTree* tree, BTreeNode* node, BTPos pos, int count, int flag);
BTreeNode* BTree_Delete(BTree* tree, BTPos pos, int count);
BTreeNode* BTree_Get(BTree* tree, BTPos pos, int count);
BTreeNode* BTree_Root(BTree* tree);
int BTree_Height(BTree* tree);
int BTree_Count(BTree* tree);
int BTree_Degree(BTree* tree);
void BTree_Display(BTree* tree, BTree_Printf* pFunc, int gap, char div);
BTree.c
#include <stdio.h>
#include "BTree.h"
typedef struct _tag_BTree TBTree;
struct _tag_BTree
{
int count;
BTreeNode* root;
};
BTree* BTree_Create()
{
TBTree* tree = (TBTree*)malloc(sizeof(TBTree));
if (tree!=NULL) {
tree->count = 0;
tree->root = NULL;
}
return tree;
}
void BTree_Destroy(BTree* tree)
{
free(tree);
}
void BTree_Clear(BTree* tree)
{
TBTree* btree = (TBTree*)tree;
if (btree != NULL) {
btree->count = 0;
btree->root = NULL;
}
}
int BTree_Insert(BTree * tree, BTreeNode * node, BTPos pos, int count, int flag)
{
TBTree* btree = (TBTree*)tree;
BTreeNode* parent = NULL;
BTreeNode* current = NULL;
int bit = 0;
int ret = (btree!=NULL && node!=NULL);
ret = ret && (flag == BT_LEFT || flag == BT_RIGHT);
if (ret) {
current = btree->root;
node->left = NULL;
node->right = NULL;
while ((count>0) && (current!=NULL)) {
bit = pos & 1;
pos = pos >> 1;
parent = current;
if (BT_LEFT == bit)
current = current->left;
else if (BT_RIGHT == bit)
current = current->right;
count--;
}
if (BT_LEFT == flag)
node->left = current;
else if (BT_RIGHT == flag)
node->right = current;
if (parent!=NULL) {
if (BT_LEFT == bit)
parent->left = node;
else if (BT_RIGHT == bit)
parent->right = node;
}
else {
btree->root = node;
}
btree->count++;
}
return ret;
}
static int recursive_count(BTreeNode* root)
{
int ret = 0;
if (root!=NULL) {
ret = recursive_count(root->left) + 1 + recursive_count(root->right);
}
return ret;
}
BTreeNode* BTree_Delete(BTree* tree, BTPos pos, int count)
{
TBTree* btree = (TBTree*)tree;
BTreeNode* ret = NULL;
BTreeNode* parent = NULL;
BTreeNode* current = NULL;
int bit = 0;
if (btree!=NULL) {
current = btree->root;
while ((count>0) && (current!=NULL)) {
bit = pos & 1;
pos = pos >> 1;
parent = current;
if (BT_LEFT == bit)
current = current->left;
else if (BT_RIGHT == bit)
current = current->right;
count--;
}
if (parent!=NULL) {
if (BT_LEFT == bit)
parent->left = NULL;
else if (BT_RIGHT == bit)
parent->right = NULL;
}
else {
btree->root = NULL;
}
ret = current;
btree->count = btree->count - recursive_count(ret);
}
return ret;
}
BTreeNode* BTree_Get(BTree* tree, BTPos pos, int count)
{
TBTree* btree = (TBTree*)tree;
int bit = 0;
BTreeNode* ret = NULL;
BTreeNode* current = NULL;
if (btree!=NULL) {
current = btree->root;
while ((count>0) && (current!=NULL)) {
bit = pos & 1;
pos = pos >> 1;
if (BT_LEFT == bit)
current = current->left;
else if (BT_RIGHT == bit)
current = current->right;
count--;
}
ret = current;
}
return ret;
}
BTreeNode* BTree_Root(BTree* tree)
{
TBTree* btree = (TBTree*)tree;
BTreeNode* ret = NULL;
if (btree!=NULL) {
ret = btree->root;
}
return ret;
}
static int recursive_height(BTreeNode* root)
{
int ret = 0;
int left = 0;
int right = 0;
if (root!=NULL) {
left = recursive_height(root->left);
right = recursive_height(root->right);
ret = left > right ? (left + 1) : (right + 1);
}
return ret;
}
int BTree_Height(BTree* tree)
{
int ret = 0;
TBTree* btree = (TBTree*)tree;
if (btree!=NULL) {
ret = recursive_height(btree->root);
}
return ret;
}
int BTree_Count(BTree* tree)
{
TBTree* btree = (TBTree*)tree;
int ret = 0;
if (btree!=NULL) {
ret = btree->count;
}
return ret;
}
static int recursive_degree(BTreeNode* root)
{
int ret = 0;
int ld = 0;
int rd = 0;
if (root!=NULL) {
if (root->left!=NULL) {
ret++;
}
if (root->right!=NULL) {
ret++;
}
if (1 == ret) {
ld = recursive_degree(root->left);
if (ret<ld) {
ret = ld;
}
rd = recursive_degree(root->right);
if (ret<rd) {
ret = rd;
}
}
}
return ret;
}
int BTree_Degree(BTree* tree)
{
TBTree* btree = (TBTree*)tree;
int ret = 0;
if (btree!=NULL) {
ret = recursive_degree(btree);
}
return ret;
}
static void recursive_display(BTreeNode* root, BTree_Printf* pFunc, int format, int gap, char div)
{
int i = 0;
if ((root!=NULL) && (pFunc!=NULL)) {
for (i = 0; i < format;++i) {
printf("%c", div);
}
pFunc(root);
printf("\n");
if ((root->left!=NULL) || (root->right!=NULL)) {
recursive_display(root->left, pFunc, format + gap, gap, div);
recursive_display(root->right, pFunc, format + gap, gap, div);
}
}
else {
for (i = 0; i < format;++i) {
printf("%c", div);
}
printf("\n");
}
}
void BTree_Display(BTree* tree, BTree_Printf* pFunc, int gap, char div)
{
TBTree* btree = (TBTree*)tree;
if (btree!=NULL) {
recursive_display(btree->root, pFunc, 0, gap, div);
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "BTree.h"
struct Node
{
BTreeNode header;
char v;
};
void printf_data(BTreeNode* node)
{
if (node != NULL) {
printf("%c", ((struct Node*)node)->v);
}
}
int main(int argc, char* argv[])
{
BTree* tree = BTree_Create();
struct Node n1 = { {NULL,NULL},'A' };
struct Node n2 = { {NULL,NULL},'B' };
struct Node n3 = { {NULL,NULL},'C' };
struct Node n4 = { {NULL,NULL},'D' };
struct Node n5 = { {NULL,NULL},'E' };
struct Node n6 = { {NULL,NULL},'F' };
BTree_Insert(tree, (BTreeNode*)&n1, 0, 0, 0);
BTree_Insert(tree, (BTreeNode*)&n2, 0x00, 1, 0);
BTree_Insert(tree, (BTreeNode*)&n3, 0x01, 1, 0);
BTree_Insert(tree, (BTreeNode*)&n4, 0x00, 2, 0);
BTree_Insert(tree, (BTreeNode*)&n5, 0x02, 2, 0);
BTree_Insert(tree, (BTreeNode*)&n6, 0x02, 3, 0);
printf("Height:%d\n", BTree_Height(tree));
printf("Degree:%d\n", BTree_Degree(tree));
printf("Count:%d\n", BTree_Count(tree));
printf("Position At (0x02,2):%c\n", ((struct Node*)BTree_Get(tree, 0x02, 2))->v);
printf("Full Tree:\n");
BTree_Display(tree, printf_data, 4, '-');
BTree_Delete(tree, 0x00, 1);
printf("After Delete B: \n");
printf("Height: %d\n", BTree_Height(tree));
printf("Degree: %d\n", BTree_Degree(tree));
printf("Count: %d\n", BTree_Count(tree));
printf("Full Tree: \n");
BTree_Display(tree, printf_data, 4, '-');
BTree_Clear(tree);
printf("After Clear: \n");
printf("Height: %d\n", BTree_Height(tree));
printf("Degree: %d\n", BTree_Degree(tree));
printf("Count: %d\n", BTree_Count(tree));
BTree_Display(tree, printf_data, 4, '-');
BTree_Destroy(tree);
return 0;
}
运行结果:
Height:4
Degree:2
Count:6
Position At (0x02,2):E
Full Tree:
A
----B
--------D
--------E
------------F
------------
----C
After Delete B:
Height: 2
Degree: 2
Count: 2
Full Tree:
A
----
----C
After Clear:
Height: 0
Degree: 0
Count: 0