#ifndef __BTREE_H__
#define __BTREE_H__
#define BLEFT 0
#define BRIGHT 1
typedef char BTreeData;
typedef struct _btreeNode //节点的类型
{
BTreeData data;
struct _btreeNode *lchild;
struct _btreeNode *rchild;
}BTreeNode;
typedef struct _btree // 指向根节点的东西
{
int count;
BTreeNode *root;
}BTree;
BTree *Create_BTree ();
int BTree_Insert (BTree *tree, BTreeData data, int pos, int count, int flag);
int Display (BTree *tree);
int Delete (BTree *tree, int pos, int count);
int BTree_height(BTree *tree);
int BTree_degree (BTree* tree);
int BTree_Delete(BTree* tree);
int BTree_Clear (BTree* tree);
#endif
下面是子函数:
#include "BTree.h"
#include <stdlib.h>
#include <stdio.h>
BTree *Create_BTree ()
{
BTree *btree = (BTree *)malloc(sizeof (BTree) / sizeof (char));
if (btree == NULL)
{
return NULL;
}
btree ->root = NULL;
btree ->count = 0;
return btree;
}
int BTree_Insert (BTree *tree, BTreeData data, int pos, int count, int flag)
{
if (tree == NULL || (flag != BLEFT && flag != BRIGHT))
{
return 0;
}
BTreeNode *node = (BTreeNode*) malloc (sizeof (BTreeNode) / sizeof (char));
if (node == NULL)
{
return 0;
}
node ->data =data;
node ->lchild = NULL;
node ->rchild = NULL;
//找插入位置
BTreeNode *parent = NULL;
BTreeNode *current = tree ->root; //current一开始指向根节点
int way; //保存当前走的位置
while (count > 0 && current != NULL)
{
way = pos & 1;
pos = pos >> 1;
parent = current;
if (way == BLEFT)
current = current ->lchild;
else
current = current ->rchild;
count --;
}
//flag =way;
//挂在以前的节点上
if (flag == BLEFT)
node ->lchild = current;
else
node ->rchild = current;
//把新节点插入二叉树中
if (parent != NULL)
{
if (way == BLEFT)
parent ->lchild = node;
else
parent ->rchild = node;
}
else
{
tree ->root = node;
}
tree ->count ++;
return 0;
}
r_display (BTreeNode* node, int gap)
{
int i;
if (node == NULL)
{
for (i = 0; i < gap; i++)
{
printf ("*");
}
printf ("\n");
return;
}
for (i = 0; i < gap; i++)
printf ("*");
printf ("%c\n", node ->data);
r_display (node ->lchild, gap + 4);
r_display (node ->rchild, gap + 4);
}
int Display (BTree *tree)
{
if (tree == NULL)
return 0;
r_display (tree ->root,0);
}
void r_delete (BTree *tree, BTreeNode* node)
{
if (node == NULL || tree == NULL)
return;
r_delete (tree,node ->lchild);
r_delete (tree,node ->rchild);
free (node);
tree ->count --;
}
int Delete (BTree *tree, int pos, int count)
{
if (tree == NULL)
return 0;
BTreeNode *parent = NULL;
BTreeNode *current = tree ->root; //current一开始指向根节点
int way; //保存当前走的位置
while (count > 0 && current != NULL)
{
way = pos & 1;
pos = pos >> 1;
parent = current;
if (way == BLEFT)
current = current ->lchild;
else
current = current ->rchild;
count --;
}
//把新节点插入二叉树中
if (parent != NULL)
{
if (way == BLEFT)
parent ->lchild = NULL;
else
parent ->rchild = NULL;
}
else
{
tree ->root = NULL;
}
r_delete(tree,current);
}
//树的高度
int r_height (BTreeNode* node)
{
if (node ==NULL)
{
return 0;
}
int lh =r_height (node ->lchild);
int rh =r_height (node ->rchild);
return (lh > rh ? lh+1 : rh+1);
}
int BTree_height(BTree *tree)
{
if (tree == NULL)
return 0;
int net = r_height(tree ->root);
printf ("%d\n",net);
return 1;
}
//求树的度
int r_degree (BTreeNode* node)
{
if (node ==NULL)
return 0;
int degree = 0;
if (node ->lchild != NULL)
degree ++;
if (node ->rchild != NULL)
degree ++;
if (degree == 1)
{
int ld = r_degree (node ->lchild);
if (ld == 2)
return 2;
int rd = r_degree (node ->rchild);
if (rd ==2)
return 2;
}
return degree;
}
int BTree_degree (BTree* tree)
{
if (tree == NULL)
return 0;
int h = r_degree(tree->root);
printf ("%d\n",h);
}
//删除
int BTree_Delete(BTree* tree)
{
if (tree ==NULL)
return 0;
Delete (tree, 0, 0);
return 0;
}
//清空
int BTree_Clear (BTree* tree)
{
if (tree ==NULL)
return 0;
BTree_Delete (tree);
free (tree);
return 0;
}
主函数:
#include <stdio.h>
#include "BTree.h"
int main()
{
BTree *btree = Create_BTree ();
if (btree == NULL)
printf ("创建失败\n");
else
printf ("创建成功\n");
BTree_Insert(btree, 'A', 0, 0, 0);
BTree_Insert(btree, 'B', 0, 1, 0);
BTree_Insert(btree, 'C', 1, 1, 0);
BTree_Insert(btree, 'D', 0, 2, 0);
BTree_Insert(btree, 'E', 2, 2, 0);
BTree_Insert(btree, 'F', 0, 3, 0);
BTree_Insert(btree, 'G', 4, 3, 0);
BTree_Insert(btree, 'H', 3, 2, 0);
//BTree_Insert(btree, 'X', 0, 1, 1);
Display (btree);
Delete (btree,4,3);
printf ("删除后----------------\n");
Display (btree);
BTree_degree(btree);
printf ("\n");
BTree_height(btree);
printf ("+---------------------\n");
BTree_Clear(btree);
Display (btree);
printf ("---------------------------\n");
BTree_Destroy(&btree);
return 0;
}
二叉树的实现没有通用树那么复杂,因为二叉树只有至多两个子节点。这样我们可以轻易定义两个指针分别指向左右两个孩子。
值得注意的是插入的思路,对于插入的节点,之前位置放置的节点应接在新节点左还是右由flag输入控制,我们认为0左。而如何走到那个点,我们需要一个方法实现,设左走为0,从根节点到第一个子节点为0或1,反向计数,如,深度3的右边为001,我们记为4(100),当出现000,我们只能记为0因此我们还需要一个count来计数。这样我们便完成了步数行走,由此我们可以联想到,用01这种计数方式进行一些选择性行走,可以很简便的转化为二进制运算,这种转化方法用在一些地方可以转化为二叉树模型。记录父节点左右的时候,记录最后一次行走的方向就可以了。
对于删除与插入思想相类似。打印,高度等便是与通用树相类似的递归。