目录:

  • 代码:
  • 分析:
  • 汇编:

代码:

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) //定义递归计算度数函数
{  //最大度数只会是2int 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;//数量为0ret->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;
}

分析:










汇编:


















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

  1. 真c++ 从二叉树到红黑树(4)之二叉平衡搜索树AVL

      此文章为从二叉树到红黑树系列文章的第四节,主要介绍介绍二叉平衡搜索树AVL,当你理解了AVL,红黑树你就理解了一半了! 文章目录 一.前面文章链接~(点击右边波浪线可以返回目录) 二.由BST引入 ...

  2. 通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的

    实验目的: 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 实验过程: 通过vi程序进行编程: int g(int x) { return x + 3; } int f(int x) ...

  3. c理c利用计算机怎么弹,通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的...

    通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 计算机的工作方式: 现代计算机的基本体系结构都是采用冯诺依曼结构,冯诺依曼的设计思想最重要之处是"存储程序"的这个概念 ...

  4. Linux内核汇编代码分析

    Linux内核汇编代码分析 1.vmlinux.lds.S文件分析 1.2 vmlinux.lds.S文件总体框架 1.3 代码段 1.4 只读数据段 1.5 init段 1.6 数据段 1.7 未初 ...

  5. Algorithm:树结构(二叉树/多路查找树/字典树)的简介、具体结构(FBT/CBT/BST/BBT/Heap/Huffman、B树/B+树/R树、字典树)及其运算(增删查/遍历/旋转)、代码实现

    Algorithm:树结构(二叉树/多路查找树/字典树)的简介.具体结构(FBT/CBT/BST/BBT/Heap/Huffman.B树/B+树/R树.字典树)及其运算(增删查/遍历/旋转).代码实现 ...

  6. 【汇编语言与计算机系统结构笔记05】汇编的系统结构,从C代码生产汇编代码,一个具体的、经典的数据传送指令(mov)实例与分析

    本次笔记内容: 06.寻址模式与数据传输指令等 文章目录 汇编程序员眼中的系统结构 如何从C代码生产汇编代码 如何装gcc? 汇编语言数据格式 第一条汇编指令实例 数据传送指令(mov) 语法与操作数 ...

  7. 《ARPG游戏深度强化学习 》之实现一个Deep Q-learning Network(二叉树状态QDN(逐条分析python代码))

    实现一个Deep Q-learning Network(二叉树状态DQN) 代码主要解决的问题: 有0-6,7个状态,从上图是他们可以状态跳转的方向和关系. 我们设定状态6是最终GDAL,目标,训练a ...

  8. JS 数据结构之旅 :通过JS实现栈、队列、二叉树、二分搜索树、AVL树、Trie树、并查集树、堆

    JS 数据结构之旅 栈 概念 栈是一个线性结构,在计算机中是一个相当常见的数据结构. 栈的特点是只能在某一端添加或删除数据,遵循先进后出的原则 实现 每种数据结构都可以用很多种方式来实现,其实可以把栈 ...

  9. 反汇编代码分析--函数调用

    C++反汇编代码分析--函数调用 代码如下: #include "stdlib.h" int sum(int a,int b,int m,int n) {   return a+b ...

最新文章

  1. 自动驾驶的视觉感知包括哪些内容?
  2. shell脚本逻辑判断,文件目录属性判断,if,case用法
  3. Android学习四、Android中的Adapter
  4. Linux断点方法,一种基于Linux问题断点的定位方法及系统与流程
  5. 遇到 ORACLE 错误 1658
  6. oracle rollback 观察时间
  7. window.onload和jQuery的ready函数区别
  8. 未来五年的全球绿色数据中心市场的增长趋势和预测
  9. 自然辩证法与计算机科学的关系,科学技术与自然辩证法的关系 毕业论文
  10. Revit二次开发之ISelectionFilter 接口的用法
  11. Python : async和await、asyncio与aiofiles
  12. 贾俊平统计学思维导图- 第九章 分类数据分析
  13. 第12周 上机报告 1之练习3 回文日
  14. 【云驻共创】当HarmonyOS走进课堂是种什么体验
  15. js实现简单的点名器随机色
  16. NISP网络信息安全面试怎么选择(六)NISP管理中心
  17. kali 安装netspeed 网络流量监视器
  18. 腾讯 美团 字节 抖音 面经
  19. 互联网专利战场急先锋-高智发明,微软苹果等撑腰
  20. eve计算机配置要求,玩EVE的电脑应该怎么配置?

热门文章

  1. 详细介绍jQuery.outerWidth() 函数具体用法
  2. React后台管理系统-品类的增加、修改和查看
  3. 关于使用JQ scrollTop方法进行滚动定位
  4. 200行代码写一个简易的dva
  5. CSS块元素水平垂直居中的实现技巧
  6. Zabbix监控多个JVM进程
  7. Tomcat启用HTTPS协议配置过程
  8. 二、先在SD卡上启动U-boot,再烧写新的U-boot进Nandflash
  9. RotateDrawable
  10. 闲话杂谈—至曾经的自己