二叉树(多路平衡搜索树)-(代码、分析、汇编)

代码:

BTree.h

#ifndef _BTREE_H_
#define _BTREE_H_

#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);//声明用函数处理每个节点的函数

#endif


BTree.c

#include <stdio.h>
#include <malloc.h>
#include "BTree.h"

typedef struct _tag_BTree TBTree;//定义实际使用树类型
struct _tag_BTree
{
    
    
    int count;//节点数量
    BTreeNode* root;//根节点
};

static void recursive_display(BTreeNode* node, BTree_Printf* pFunc, int format, int gap, char div) // 定义递归处理节点函数
{
    
    
    int i = 0;
    
    if( (node != NULL) && (pFunc != NULL) )//如果节点与函数指针不为空
    {
    
    
        for(i=0; i<format; i++)//输出占位符
        {
    
    
            printf("%c", div);
        }
        
        pFunc(node);//对节点进行函数处理
        
        printf("\n");
        
        if( (node->left != NULL) || (node->right != NULL) )//如果左子节点或右子节点不为空
        {
    
    
            recursive_display(node->left, pFunc, format + gap, gap, div);//处理左子节点,占位符数量以gap递增
            recursive_display(node->right, pFunc, format + gap, gap, div);//处理右子节点,占位符数量以gap递增
        }
    }
    else//如果节点或函数指针为空 只输出占位符
    {
    
    
        for(i=0; i<format; i++)//输出占位符
        {
    
    
            printf("%c", div);
        }
        printf("\n");
    }
}

static int recursive_count(BTreeNode* root) // 递归调用计算以一个节点开始下面所有子节点数量(包括第一次的节点本身)函数
{
    
    
    int ret = 0;
    
    if( root != NULL )
    {
    
    
		//递归调用每次调用只要不是空节点都会加1 数量
        ret = recursive_count(root->left) + 1 + recursive_count(root->right);
    }
    
    return ret;
}

static int recursive_height(BTreeNode* root) // 定义递归计算树高度的函数
{
    
    
    int ret = 0;
    
    if( root != NULL )
    {
    
    
        int lh = recursive_height(root->left);
        int rh = recursive_height(root->right);
        
        ret = ((lh > rh) ? lh : rh) + 1;//取左右两边节点较多的再加上本身节点
    }
    
    return ret;//返回高度
}

static int recursive_degree(BTreeNode* root) //定义递归计算度数函数
{
    
      
	//最大度数只会是2
    int ret = 0;
    
    if( root != NULL )
    {
    
    
        if( root->left != NULL )
        {
    
    
            ret++;
        }
        
        if( root->right != NULL )
        {
    
    
            ret++;
        }
        //如果是根节点是1,表示还不是最大度数,继续往子节点寻找有没有最大度数存在
        if( ret == 1 )
        {
    
    
            int ld = recursive_degree(root->left);
            int rd = recursive_degree(root->right);
            
            if( ret < ld )//如果该节点的左子节点中有度数比该节点大
            {
    
    
                ret = ld;//取左子节点返回的度数
            }
            
            if( ret < rd )//如果右子节点中有度数比现在度数
            {
    
    
                ret = rd;//取右子节点返回的度数
            }
        }
    }
    
    return ret;//返回最终度数 
}

BTree* BTree_Create()//定义创建树函数
{
    
    
    TBTree* ret = (TBTree*)malloc(sizeof(TBTree));//申请使用的树空间
    
    if( ret != NULL )//申请成功
    {
    
    
        ret->count = 0;//数量为0
        ret->root = NULL;//根节点为空
    }
    
    return ret;//返回创建树
}

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;
    }
}
/* count 表示插入节点的上面有多少层节点
   flag 表示原来该位置的节点位于插入节点的方向
*/
int BTree_Insert(BTree* tree, BTreeNode* node, BTPos pos, int count, int flag) // 定义插入节点函数
{
    
    
    TBTree* btree = (TBTree*)tree;//转换成使用树类型
	//判断树与插入节点不为空,和flag标识是左边或右边
    int ret = (btree != NULL) && (node != NULL) && ((flag == BT_LEFT) || (flag == BT_RIGHT));
    int bit = 0;
    
    if( ret )
    {
    
    
        BTreeNode* parent = NULL;
        BTreeNode* current = btree->root;
        
        node->left = NULL;//将插入节点的左子节点设空
        node->right = NULL;//将插入节点的右子节点设空
        
        while( (count > 0) && (current != NULL) )//找到插入的位置
        {
    
    
            bit = pos & 1;//判断pos是奇数还是偶数 (奇数往右偶数往左)
            pos = pos >> 1;
            
            parent = current;//父节点赋值
            
            if( bit == BT_LEFT )//如果是左边
            {
    
    
                current = current->left;//取得节点左子节点指向
            }
            else if( bit == BT_RIGHT )//如果是右边
            {
    
    
                current = current->right;//取得节点右子节点指向
            }
            
            count--;
        }
        
        if( flag == BT_LEFT )//如插入位置是左子节点
        {
    
    
            node->left = current;//将本来在该位置的节点设为新插入节点的左子节点
        }
        else if( flag == BT_RIGHT )//如果插入位置是右子节点
        {
    
    
            node->right = current;//将本来在该位置的节点设为新插入节点的右子节点
        }
        
        if( parent != NULL )//如果父节点不为空
        {
    
    
            if( bit == BT_LEFT )
            {
    
    
                parent->left = node;//父节点的左子节点指向新插入节点 
            }
            else if( bit == BT_RIGHT )
            {
    
    
                parent->right = node;//父节点的右子节点指向新插入节点
            }
        }
        else//父节点为表示是
        {
    
    
            btree->root = node;//将新插入节点当作根节点
        }
        
        btree->count++;//树节点数量增加
    }
    
    return ret;
}

BTreeNode* BTree_Delete(BTree* tree, BTPos pos, int count) // 定义删除节点函数
{
    
    
	/*
	注意:删除节点后面,删除的节点与其子节点都不在树中,而且删除的节点和其子节点的left
	      和right 没置空,还保持着对应关系 
	*/
    TBTree* btree = (TBTree*)tree;//取得树
    BTreeNode* ret = NULL; 
    int bit = 0;
    
    if( btree != NULL )//树不为空
    {
    
    
        BTreeNode* parent = NULL;
        BTreeNode* current = btree->root;//取得根节点
        
        while( (count > 0) && (current != NULL) )//取得删除节点
        {
    
    
            bit = pos & 1;
            pos = pos >> 1;
            
            parent = current;
            
            if( bit == BT_LEFT )
            {
    
    
                current = current->left;
            }
            else if( bit == BT_RIGHT )
            {
    
    
                current = current->right;
            }
            
            count--;
        }
        
        if( parent != NULL )//如果父节点不为空
        {
    
    
            if( bit == BT_LEFT )//如果删除节点是父节点的左边
            {
    
    
                parent->left = NULL;//将父节点的左子节点置空不指向删除节点了
            }
            else if( bit == BT_RIGHT )//如果删除节点是父节点的右边
            {
    
    
                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;//取得树
    BTreeNode* ret = NULL; 
    int bit = 0;
    
    if( btree != NULL )//树不为空
    {
    
    
        BTreeNode* current = btree->root;//取得根节点
        
        while( (count > 0) && (current != NULL) )//找到要获取的节点
        {
    
    
            bit = pos & 1;
            pos = pos >> 1;
            
            if( bit == BT_LEFT )
            {
    
    
                current = current->left;
            }
            else if( bit == BT_RIGHT )
            {
    
    
                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;//获取根节点
}

int BTree_Height(BTree* tree) // 定义获取树高度函数
{
    
    
    TBTree* btree = (TBTree*)tree;
    int ret = 0;
    
    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;//返回数量
}

int BTree_Degree(BTree* tree) // 定义获取树度数函数
{
    
    
    TBTree* btree = (TBTree*)tree;//取得树
    int ret = 0;
    
    if( btree != NULL )
    {
    
    
        ret = recursive_degree(btree->root);//用根节点调用递归计算度数函数
    }
    
    return ret;//返回度数 
}

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);
    
	getchar();
	return 0;
}

分析:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

汇编:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_37599645/article/details/112028835