二叉树的基本操作

本文中所使用的栈、队列的基本操作均在《顺序栈》、《链式队列》中。
链接:
https://blog.youkuaiyun.com/lw13572259173/article/details/82927983
https://blog.youkuaiyun.com/lw13572259173/article/details/84866916

二叉树的定义

typedef int BDataType;
typedef struct BTNode
{
	struct BTNode* pLeft; //左孩子
	struct BTNode* pRight; //右孩子
	BDataType data;
}BTNode, *pBTNode;

创建新结点

pBTNode BTBuyNode(BDataType d)
{
	pBTNode newNode = (pBTNode)malloc(sizeof(BTNode));
	if (NULL == newNode)
	{
		assert(0);
	}
	newNode->data = d;
	newNode->pLeft = NULL;
	newNode->pRight = NULL;
	return newNode;
}

前序遍历

递归
void PreOrder(pBTNode pbtree)
{
	//树不为空
	if (pbtree)
	{
		printf("%d ", pbtree->data);//遍历根节点
		PreOrder(pbtree->pLeft);//遍历左孩子
		PreOrder(pbtree->pRight);//遍历右孩子
	}
}
非递归
方法1
void PreOrderNor1(pBTNode pbtree)
{
	//树不为空
	if (NULL == pbtree)
	{
		return;
	}
	Stack stack;
	StackInit(&stack);//初始化
	//根结点入栈
	StackPush(&stack, (int)pbtree);//压栈
	while (!StackEmpty(&stack))//栈是否为空
	{
		pBTNode btnode = (pBTNode)StackTop(&stack);//查看栈顶元素
		printf("%d ", btnode->data);
		StackPop(&stack);//出栈
		if (btnode->pRight) //右孩子存在
		{
			StackPush(&stack, (int)(btnode->pRight));//压栈
		}
		if (btnode->pLeft) //左孩子存在
		{
			StackPush(&stack, (int)(btnode->pLeft));//压栈
		}
	}
}
方法2
void PreOrderNor2(pBTNode pbtree)
{
	//树不为空
	if (NULL == pbtree)
	{
		return;
	}
	Stack stack;
	StackInit(&stack);//初始化
	StackPush(&stack, (int)pbtree);//压栈
	while (!StackEmpty(&stack))//栈是否为空
	{
		pBTNode btnode = (pBTNode)StackTop(&stack);//查看栈顶元素
		StackPop(&stack);//出栈
		while (btnode)
		{
			printf("%d ", btnode->data);
			if (btnode->pRight) //右孩子存在
			{
				StackPush(&stack, (int)(btnode->pRight));//压栈
			}
			btnode = btnode->pLeft;
		}
	}
}

中序遍历

递归
void InOrder(pBTNode pbtree)
{
	//树不为空
	if (pbtree)
	{
		InOrder(pbtree->pLeft);//遍历左孩子
		printf("%d ", pbtree->data);//打印根节点
		InOrder(pbtree->pRight);//遍历右孩子
	}
}
非递归
void InOrderNor(pBTNode pbtree)
{
	//树不为空
	if (NULL == pbtree)
	{
		return;
	}
	Stack stack;
	StackInit(&stack);//初始化
	pBTNode cur = pbtree;
	//找到最左端的结点
	while (!StackEmpty(&stack) || NULL != cur)//根结点
	{
		while (NULL != cur) //遍历左子树
		{
			StackPush(&stack, (int)cur);//压栈
			cur = cur->pLeft;
		}
		cur = (pBTNode)StackTop(&stack);//查看栈顶元素
		printf("%d ", cur->data);//遍历根节点
		StackPop(&stack);//出栈
		cur = cur->pRight;//以右子树为根节点
	}
}

后序遍历

递归
void PostOrder(pBTNode pbtree)
{
	//树不为空
	if (pbtree)
	{
		PostOrder(pbtree->pLeft);//遍历左孩子
		PostOrder(pbtree->pRight);//遍历右孩子
		printf("%d ", pbtree->data);//遍历根节点
	}
}
非递归
void PostOrderNor(pBTNode pbtree)
{
	//树不为空
	if (NULL == pbtree)
	{
		return;
	}
	Stack stack;
	StackInit(&stack);//初始化
	pBTNode cur = pbtree;
	pBTNode pPrev = NULL; //标记
	while (!StackEmpty(&stack) || NULL != cur)
	{
		while (NULL != cur) //遍历左子树
		{
			StackPush(&stack, (int)cur);//压栈
			cur = cur->pLeft;
		}
		pBTNode pTop = (pBTNode)StackTop(&stack);//查看栈顶元素
		if (NULL == pTop->pRight || pTop->pRight == pPrev) //不能直接遍历根结点,需要右子树为空或者右子树已经遍历过
		{
			printf("%d ", pTop->data);//遍历根节点
			pPrev = pTop;
			StackPop(&stack);//出栈
		}
		else
		{
			cur = pTop->pRight; //遍历右节点
		}
	}
}

创建二叉树

void CreateBinTree(pBTNode* pbtree, const char* str, int size, int* count)
{
	if (size > *count && *(str + (*count)) != '#')
	{
		*pbtree = BTBuyNode(*(str + (*count)++)); //创建根结点
		CreateBinTree(&((*pbtree)->pLeft), str, size, count); //创建左子树
		CreateBinTree(&((*pbtree)->pRight), str, size, count); //创建右子树
	}
	else
	{
		(*count)++;
	}
}

拷贝二叉树

void CopyeBinTree(pBTNode pbtree, pBTNode* pnewbtree)
{
	if (pbtree)
	{
		*pnewbtree = BTBuyNode(pbtree->data); //创建根结点
		CopyeBinTree(pbtree->pLeft, &((*pnewbtree)->pLeft));
		CopyeBinTree(pbtree->pRight, &((*pnewbtree)->pRight));
	}
}

销毁二叉树

void DestnyBinTree(pBTNode* pbtree)
{
	if (*pbtree)
	{
		DestnyBinTree(&((*pbtree)->pLeft));
		DestnyBinTree(&((*pbtree)->pRight));
		free(*pbtree);
		*pbtree = NULL;
	}
}

结点个数

int GetBTNodeCount(pBTNode pbtree)
{
	if (pbtree == NULL)//根结点不存在
		return 0;
	return GetBTNodeCount(pbtree->pLeft) + GetBTNodeCount(pbtree->pRight) + 1;//根结点存在
}

叶子结点个数

int GetLeafBTNodeCount(pBTNode pbtree)
{
	if (pbtree == NULL)//根结点不存在
		return 0;
	if (NULL == pbtree->pLeft &&NULL == pbtree->pRight) //左右孩子不存在
		return 1;
	return GetLeafBTNodeCount(pbtree->pLeft) + GetLeafBTNodeCount(pbtree->pRight);
}

第k层结点

int GetKLevelBTNodeCount(pBTNode pbtree, BDataType k)
{
	if (pbtree == NULL)//根结点不存在
		return 0;
	if (k <= 0)
		return 0;
	if (1 == k)
		return 1;
	return GetKLevelBTNodeCount(pbtree->pLeft, k - 1) + GetKLevelBTNodeCount(pbtree->pRight, k - 1);
}

树的高度

int Height(pBTNode pbtree)
{
	if (NULL == pbtree)
		return 0;
	int highL = Height(pbtree->pLeft);
	int highR = Height(pbtree->pRight);
	return highL > highR ? highL + 1 : highR + 1;
}

获取左孩子结点

pBTNode BTNodeLeft(pBTNode pNode)
{
	if (NULL == pNode)
		return NULL;
	return pNode->pLeft;
}

获取右孩子结点

pBTNode BTNodeRight(pBTNode pNode)
{
	if (NULL == pNode)
		return NULL;
	return pNode->pRight;
}

判断一个结点是否在一颗二叉树上

int IsBTNodeInBintree(pBTNode pbtree, pBTNode pNode)
{
	if (NULL == pbtree || NULL == pNode) //树为空或结点为空
	{
		return 0;
	}
	if (pNode == pbtree) //结点为根
	{
		return 1;
	}
	if (IsBTNodeInBintree(pbtree->pLeft, pNode)) //结点在左子树
	{
		return 1;
	}
	if (IsBTNodeInBintree(pbtree->pRight, pNode)) //结点在右子树
	{
		return 1; //可以直接返回此次调用的返回值
		//return IsBTNodeInBintree(pbtree->pRight, pNode);
	}
	return 0;
}

获得一个结点的双亲结点

pBTNode GetNodeParent(pBTNode pbtree, pBTNode pNode)
{
	pBTNode parent = NULL;
	if (NULL == pbtree || NULL == pNode) //树为空或结点为空
	{
		return NULL;
	}
	if (pNode == pbtree) //结点为根
	{
		return NULL;
	}
	if (pNode == pbtree->pLeft || pNode == pbtree->pRight) //为根的左孩子或者右孩子
	{
		return pbtree;
	}
	if (parent = GetNodeParent(pbtree->pLeft, pNode)) //以根的左孩子为根结点
	{
		return parent;
	}
	if (parent = GetNodeParent(pbtree->pRight, pNode)) //以根的右孩子为根结点
	{
		return parent; //可以直接返回此次调用的返回值
		//return GetNodeParent(pbtree->pRight, pNode);
	}
	return NULL;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值