DC- 20 :二叉树

#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这种计数方式进行一些选择性行走,可以很简便的转化为二进制运算,这种转化方法用在一些地方可以转化为二叉树模型。记录父节点左右的时候,记录最后一次行走的方向就可以了。

        对于删除与插入思想相类似。打印,高度等便是与通用树相类似的递归。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值