35 创建二叉树

生活中的指路

在这里插入图片描述

指路法定位节点

在这里插入图片描述

在C语言中可以利用 语言中可以利用bit位进行指路 bit位进行指路。。

在这里插入图片描述

定义与单链表极其相识【可以对比单链表】

在这里插入图片描述

定位

在这里插入图片描述

代码:二叉树结构的实现

BTree.h

#pragma once

#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);

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 && pFunc) {
		for ( i = 0; i < format; i++)
		{
			printf("%c", div);
		}

		pFunc(node);
		printf("\n");

		if ((node->left!=NULL) || (node->right)!=NULL) {//作用:【和下面配合使用】如果节点的left和right均为NULL,则left和right子节点都不打印
			recursive_display(node->left, pFunc, format + gap, gap, div);
			recursive_display(node->right, pFunc, format + gap, gap, div);

		}

	}
	else
	{
		//作用:如果节点的left为NULL,right有值,那么把空节点【left】打印出来,为----
		for (i = 0; i < format; i++)
		{
			printf("%c", div);
		}
		printf("\n");
	}
}

//二叉树的度最大为2
static int recursive_degree(BTreeNode* root) {
	int ret = 0;

	if (root) {

		//
		if (root->left != NULL)
		{
			ret++;
		}
		if (root->right != NULL)
		{
			ret++;
		}

		//根结点只有左子树或右子树
		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;
}

static int recursive_count(BTreeNode* root) {
	int ret = 0;

	if (root) {
		ret = recursive_count(root->left) + 1 + recursive_count(root->right);
	}

	return ret;
}

static int recursive_height(BTreeNode* root) {
	int ret = 0;

	if (root) {
		int lh = recursive_height(root->left);
		int rh = recursive_height(root->right);
		return ((lh > rh) ? lh : rh) + 1;
	}

	return ret;
}

BTree* BTree_Create() {
	TBTree* ret = malloc(sizeof(TBTree));

	if (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 (btree) {
		btree->count = 0;
		btree->root = NULL;
	}
}

//flag:在插入到已有节点时,已有节点【即子树】,是放在新节点的 左子边 还是 右子边。参考图
int BTree_Insert(BTree* tree, BTreeNode* node, BTPos pos, int count, int flag) {
	TBTree* btree = (TBTree*)tree;

	int ret = (btree) && (node) && ((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 >> 1;

			parent = current;

			if (bit == BT_LEFT) {
				current = current->left;
			}
			else if(bit == BT_RIGHT){
				current = current->right;
			}

			count--;
		}

		if (flag == BT_LEFT) {//flag参数起作用
			node->left = current;
		}
		else if(flag == BT_RIGHT)
		{
			node->right = current;
		}

		if (parent) {
			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) {
	TBTree* btree = (BTree*)tree;
	BTreeNode* ret = NULL;
	int bit = 0;

	if (btree) {
		BTreeNode* parent = NULL;
		BTreeNode* current = btree->root;

		//current移动
		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) {
			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);//btree->cout减少的是该节点,再加上 子树的所有的 节点数量
	}

	return ret;
}

BTreeNode*	BTree_Get(BTree* tree, BTPos pos, int count) {
	TBTree* btree = (TBTree*)tree;
	BTreeNode* ret = NULL;
	int bit = 0;

	if (btree) {
		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){
		ret = btree->root;
	}

	return ret;
}

int BTree_Height(BTree* tree) {
	TBTree* btree = (TBTree*)tree;
	int ret = 0;

	if (btree) {
		ret = recursive_height(btree->root);
	}
}

int BTree_Count(BTree* tree) {
	TBTree* btree = (TBTree*)tree;
	int ret = 0;

	if (btree) {
		ret = btree->count;
	}

	return ret;
}

int BTree_Degree(BTree* tree) {
	TBTree* btree = (TBTree*)tree;
	int ret = 0;

	if (btree) {
		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) {
		recursive_display(btree->root, pFunc, 0, gap, div);
	}
}

main.c

//二叉树
#include"Btree.h"
#include<stdio.h>
struct Node {//类似单链表
	BTreeNode header;
	char v;
};
void printf_data(BTreeNode* node) {
	if (node) {
		printf("%c", ((struct Node*)node)->v);
	}
}

int main() {
	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, 0x00, 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("pos 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);

}

代码中一些片段说明:

插入的示意图

请添加图片描述

插入时:子树放到新节点的左边还是右边?

在这里插入图片描述
通俗而言:current节点其实已经被抛弃了

代码中的树长什么样?

请添加图片描述
打印函数修改:如果 某个节点 的left节点存在,right节点不存在,那么right节点打印为-----【空】

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值