既然树已经熟悉了,那我们就来学习学习二叉树吧,二叉树是由n(n>=0)个结点组成的有限集合,该集合或者为空,或者是由一个根结点加上两棵分别称为左子树和右子树的﹑互不相交的二叉树组成。
如图
有两个定义需要大家知道下:
1.满二叉树
如果二叉树中所有分支结点的度数都为2,且叶子结点都在同一层次上,则称这类二叉树为满二叉树。
2.完全二叉树
如果一棵具有n个结点的高度为k的二叉树,它的每一个结点都与高度为k的满二叉树中编号为1-n的结点一一对应,则称这棵二叉树为完全二叉树。(从上到下从左到右编号)
完全二叉树的叶结点仅出现在最下面两层
最下层的叶结点一定出现在左边
倒数第二层的叶结点一定出现在右边
完全二叉树中度为1的结点只有左孩子
同样结点数的二叉树,完全二叉树的高度最小
二叉树所具有的5个性质需要大家掌握:
这里介绍通用树的常用操作:
l 创建二叉树
l 销毁二叉树
l 清空二叉树
l 插入结点到二叉树中
l 删除结点
l 获取某个结点
l 获取根结点
l 获取二叉树的高度
l 获取二叉树的总结点数
l 获取二叉树的度
l 输出二叉树
代码总分为三个文件:
BTree.h : 放置功能函数的声明,以及树的声明,以及树结点的定义
BTree.c : 放置功能函数的定义,以及树的定义
Main.c : 主函数,使用功能函数完成各种需求,一般用作测试
整体结构图为:
这里详细说下插入结点操作,删除结点操作和获取结点操作:
插入结点操作:
如图:
删除结点操作:
如图:
获取结点操作:
获取结点操作和插入删除结点操作中的指路法定位结点相同
OK! 上代码:
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; }; BTree* BTree_Create() { TBTree* ret = (TBTree*)malloc(sizeof(TBTree)); if(NULL != ret) { ret->count = 0; ret->root = NULL; } return ret; } void BTree_Destroy(BTree* tree) { free(tree); } void BTree_Clear(BTree* tree) { TBTree* btree = (TBTree*)tree; if(NULL != btree) { btree->count = 0; btree->root = NULL; } } int BTree_Insert(BTree* tree, BTreeNode* node, BTPos pos, int count, int flag) { TBTree* btree = (TBTree*)tree; int ret = (NULL!=btree) && (NULL!=node) && ((flag == BT_RIGHT) || (flag == BT_LEFT)); int bit = 0; if(ret) { BTreeNode* parent = NULL; BTreeNode* current = btree->root; node->left = NULL; node->right = NULL; while((0 < count) && (NULL != current)) { 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(NULL != parent) { 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(NULL != root) { 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; int bit = 0; if(NULL != btree) { BTreeNode* parent = NULL; BTreeNode* current = btree->root; while((0 < count) && (NULL != current)) { bit = pos & 1; pos = pos >> 1; parent = current; if(BT_RIGHT == bit) { current = current->right; } else if(BT_LEFT == bit) { current = current->left; } count--; } if(NULL != parent) { 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; BTreeNode* ret = NULL; int bit = 0; if(NULL != btree) { BTreeNode* current = btree->root; while((0<count) && (NULL!=current)) { bit = pos & 1; pos = pos >> 1; if(BT_RIGHT == bit) { current = current->right; } else if(BT_LEFT == bit) { current = current->left; } count--; } ret = current; } return ret; } BTreeNode* BTree_Root(BTree* tree) { TBTree* btree = (TBTree*)tree; BTreeNode* ret = NULL; if(NULL != btree) { ret = btree->root; } return ret; } static int recursive_height(BTreeNode* root) { int ret = 0; if(NULL != root) { int lh = recursive_height(root->left); int rh = recursive_height(root->right); ret = ((lh > rh) ? lh : rh) + 1; } return ret; } int BTree_Height(BTree* tree) { TBTree* btree = (TBTree*)tree; int ret = -1; if(NULL != btree) { ret = recursive_height(btree->root); } return ret; } int BTree_Count(BTree* tree) { TBTree* btree = (TBTree*)tree; int ret = -1; if(NULL != btree) { ret = btree->count; } return ret; } static int recursive_degree(BTreeNode* root) { int ret = 0; if(NULL != root) { if(NULL != root->left) { ret++; } if(NULL != root->right) { ret++; } if(1 == ret) { int ld = recursive_degree(root->left); int rd = recursive_degree(root->right); if(ret < ld) { ret = ld; } if(ret < rd) { ret = rd; } } } return ret; } int BTree_Degree(BTree* tree) { TBTree* btree = (TBTree*)tree; int ret = -1; if(NULL != btree) { ret = recursive_degree(btree->root); } return ret; } static void recursive_display(BTreeNode* node, BTree_Printf* pFunc, int format, int gap, char div) { int i = 0; if((NULL != node) && (NULL != pFunc)) { for(i=0; i<format; i++) { printf("%c", div); } pFunc(node); printf("\n"); if((NULL != node->left) || (NULL != node->right)) { recursive_display(node->left, pFunc, format+gap, gap, div); recursive_display(node->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(NULL != btree) { recursive_display(btree->root, pFunc, 0, gap, div); } }
Main.c :
#include <stdio.h> #include <stdlib.h> #include "BTree.h" typedef struct _tag_node { BTreeNode header; char v; }Node; void printf_data(BTreeNode* node) { if(NULL != node) { printf("%c", ((Node*)node)->v); } } int main(void) { BTree* tree = BTree_Create(); Node n1 = {{NULL, NULL}, 'A'}; Node n2 = {{NULL, NULL}, 'B'}; Node n3 = {{NULL, NULL}, 'C'}; Node n4 = {{NULL, NULL}, 'D'}; Node n5 = {{NULL, NULL}, 'E'}; 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", ((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)); printf("Full Tree:\n"); BTree_Display(tree, printf_data, 4, '-'); BTree_Destroy(tree); return 0; }
一步一步学数据结构之1--n(二叉树)
最新推荐文章于 2024-09-07 14:22:27 发布
