数据结构(26)二叉树
2015-08-11 15:04
615 查看
既然树已经熟悉了,那我们就来学习学习二叉树吧,二叉树是由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 :
[cpp] view
plaincopy
#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 :
[cpp] view
plaincopy
#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 :
[cpp] view
plaincopy
#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.满二叉树
如果二叉树中所有分支结点的度数都为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 :
[cpp] view
plaincopy
#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 :
[cpp] view
plaincopy
#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 :
[cpp] view
plaincopy
#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;
}
相关文章推荐
- 数据结构(25)树
- 数据结构(24)队列--两个栈实现
- 数据结构(23)队列--单链表实现
- 数据结构(22)循环队列--线性表实现
- 数据结构(21)队列--线性表实现
- 数据结构(20)栈--单链表实现
- 数据结构(19)栈的线性实现
- 数据结构(18)双向循环链表
- 数据结构(17)双向链表
- 数据结构(16)循环链表
- 数据结构实验之栈一:进制转换 SDUT 2131
- 数据结构07:查找
- 数据结构实验之链表四:有序链表的归并
- 【数据结构】基本概念
- 数据结构:define实现链表
- 数据结构实验之链表三:链表的逆置
- 数据结构实验之链表二:逆序建立链表
- 数据结构实验之链表一:顺序建立链表
- 数据结构_选择排序
- (原创)数据结构---树(Python)