二叉树的创建和基本操作

二叉树的基本单位和链表一样是以节点为单位

二叉树的节点的存储分为3个部分

1.存放数据     2.存放指向左子树的指针   3.存放指向右子树的指针

typedef char TDateType;
typedef struct BinaryTreeNode
{
	TDateType date;
	struct BinaryTreeNode *left; //指向左子树的指针
	struct BinaryTreeNode *right; //指向右子树的指针
}BTNode;

接下来是二叉树的基本接口

BTNode *BinaryTreeCreate(TDateType *a,int n,int *pi); //二叉树的创建
void BinaryTreeDestory(BTNode* root); //二叉树的销毁

int BinaryTreeSize(BTNode* root); //节点数
int BinaryTreeLeafSize(BTNode* root); //叶节点数
int BinaryTreeLevelKSize(BTNode* root, int k); //第K层的结点数

// 遍历  递归
void BinaryTreePrevOrder(BTNode* root); //前序
void BinaryTreeInOrder(BTNode* root); //中序
void BinaryTreePostOrder(BTNode* root); //后序
void BinaryTreeLevelOrder(BTNode* root); //层序

1.二叉树的创建

BTNode *BuyBTNode(TDateType x)//创建一个节点
{
	BTNode *node = (BTNode *)malloc(sizeof(BTNode));
	node->left = NULL;
	node->right = NULL;
	node->date = x;
	return node;
}

BTNode *BinaryTreeCreate(TDateType *a,int n,int *pi)
{
	if(a[*pi] != '#')
	{
		BTNode *root = BuyBTNode(a[*pi]);//不为空就创建节点
		(*pi)++; //左子树的创建
		root->left = BinaryTreeCreate(a,n,pi);

		(*pi)++;//右子树的创建
		root->right
			= BinaryTreeCreate(a,n,pi);

		return root;
	}
	else
	{
		return NULL;
	}
}

二叉树的创建就是先化成子问题然后利用递归的方法完成创建      先创建一个节点然后创建左子树,右子树,然后递归。

2.二叉树的销毁

void BinaryTreeDestory(BTNode* root)
{
	if(root != NULL)
	{
		if(root->left)
		{
			BinaryTreeDestory(root->left);
			root->left = NULL;
		}
		if(root->right)
		{
			BinaryTreeDestory(root->right);
			root->right = NULL;
		}
		if(root != NULL)
		{
			free(root);
			root = NULL;
		}
	}	
}

销毁也是递归的思想也是化成子问题但是和创建的顺序不一样  因为如果销毁根节点就无法访问到左子树和右子树了  所以先销毁左子树然后右子树最后销毁根节点,注意最后不要忘记置成空,防止变成野指针。

3.二叉树的节点数计算

int BinaryTreeSize(BTNode* root)
{
	if(root == NULL)
	{
		return 0;
	}
	return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

同样我们分解成子问题  总结点数等于左子树+右子树+根节点  然后利用递归就可以算出、

4.二叉树的叶节点个数

int BinaryTreeLeafSize(BTNode* root)
{
	if(root == NULL)
	{
		return 0;
	}
	if(root->left == NULL && root->right == NULL)
	{
		return 1;
	}
	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

和总节点的计算方法类似 ,区别在于加上限定的条件,每次遇到叶节点返回1 最后将左子树的叶节点和右子树的叶节点相加

5.第K层的节点数

int BinaryTreeLevelKSize(BTNode* root, int k)
{
	if(k == 0)
	{
		return 0;
	}
	if(k == 1)
	{
		return 1;
	}
	return BinaryTreeLevelKSize(root->left,k-1) + BinaryTreeLevelKSize(root->right,k-1);
}

计算第K层的节点数 我们可以看成计算第K-1层的左子树+右子树  然后利用递归解决

6.二叉树的前中后序遍历

void BinaryTreePrevOrder(BTNode* root)//前序
{
	if(root == NULL)
	{
		return ;
	}
	printf("%c ",root->date);
	BinaryTreePrevOrder(root->left);
	BinaryTreePrevOrder(root->right);
}

void BinaryTreeInOrder(BTNode* root)//中序
{
	if(root == NULL)
	{
		return ;
	}
	BinaryTreeInOrder(root->left);
	printf("%c ",root->date);
	BinaryTreeInOrder(root->right);
}

void BinaryTreePostOrder(BTNode* root)//后序
{
	if(root == NULL)
	{
		return ;
	}
	BinaryTreePostOrder(root->left);
	BinaryTreePostOrder(root->right);
	printf("%c ",root->date);
}

前中后序的遍历方法分为递归和非递归 ,这次就先介绍递归的方法

递归的方法同样是化成子问题前中后序遍历的顺序不一样 化成的子问题就不一样

前序:根节点  左子树   右子树

中序:左子树 根节点 右子树

后序:左子树 右子树 根节点

这就是二叉树的建立和基本操作

猜你喜欢

转载自blog.csdn.net/Amour_Old_flame/article/details/81916107