二叉树的基本实现(一)

这一篇博客我总结一下部分二叉树的基本操作:

1、根据数组递归创建二叉树

2、递归实现前序遍历

3、递归实现中序遍历

4、递归实现后序遍历

5、前序,中序和后序的非递归实现

6、两种方法实现层序遍历

7、递归实现求深度

8、递归实现求最远两个节点距离

9、递归实现查找节点



二叉树的这些递归实现都可以非递归实现大笑

//头文件
typedef struct BinaryTreeNode
{
	int _data;
	BinaryTreeNode* _leftchild;
	BinaryTreeNode* _rightchild;
}BinaryTreeNode,*pBinaryTreeNode;

typedef struct BinaryTree
{
	BinaryTreeNode *_root;
}BinaryTree,*pBinaryTree;

BinaryTreeNode* BuyTreeNode(int data)
{
	BinaryTreeNode* pnewNode=(BinaryTreeNode*)malloc(sizeof(BinaryTreeNode));
	if(pnewNode==NULL)
	{
		printf("memory is out\n");
		exit(EXIT_FAILURE);
	}
	pnewNode->_data=data;
	pnewNode->_leftchild=NULL;
	pnewNode->_rightchild=NULL;
	return pnewNode;
}

接下来我们看第一个实现,根据数组递归创建二叉树,‘#’表示要创建空节点,数组以前序遍历给出,同样我们创建也是根据前序遍历实现

BinaryTreeNode* RCreatBinaryTreeByPeorderTraversal(const int arr[],const int size,int& index,const int k)
{
	BinaryTreeNode* pnewNode=NULL;
	if(arr[index]!=k&&index<size)
	{
		pnewNode=BuyTreeNode(arr[index]);
		
		pnewNode->_leftchild=RCreatBinaryTreeByPeorderTraversal(arr,size,++index,k);
		pnewNode->_rightchild=RCreatBinaryTreeByPeorderTraversal(arr,size,++index,k);
	}
	return pnewNode;
}

注意这里的inde要用引用形式传到函数里,因为不管他在那一层递归里,我们需要不断使下标往前走,因此每一层对index的++ 都要真正的改变其值。
而且这里偶们最好对一些固定不变的参数加const,防止其值意外地被我们改变。
前序遍历的特点就是先打印根节点的值,再打印左孩子节点的值,最后打印右孩子节点的值。
//递归版本
void RPreOrder(BinaryTreeNode* root)
{
	if(root==NULL)
		return;
	printf("%d\n",root->_data);
	RPreOrder(root->_leftchild);
	RPreOrder(root->_rightchild);
}

中序遍历是先打印左节点,再打印根节点,最后打印右节点
//递归版本
void RInOrder(BinaryTreeNode* root)
{
	if(root==NULL)
		return ;
	RInOrder(root->_leftchild);
	printf("%d\n",root->_data);
	RInOrder(root->_rightchild);

}

后序遍历是先打印左节点,再打印右节点,最后打印根节点
//递归版本
void RPostOrder(BinaryTreeNode* root)
{
	if(root==NULL)
		return ;
	RPostOrder(root->_leftchild);
	if(root->_rightchild)
	{
		RPostOrder(root->_rightchild);	
	}

	printf("%d\n",root->_data);
}

以上都是递归实现,下面贴出来非递归版本
void PreOrder(BinaryTreeNode* root)
{
	BinaryTreeNode* pcurNode=NULL;
	stack<BinaryTreeNode*> s;
	assert(root);
	s.push(root);
	while(!s.empty())
	{
		pcurNode=s.top();
		s.pop();
		printf("%d\n",pcurNode->_data);
		if(pcurNode->_rightchild)
		{
			s.push(pcurNode->_rightchild);
		}
		if(pcurNode->_leftchild)
		{
			s.push(pcurNode->_leftchild);
		}

	}
	
}
void InOrder(BinaryTreeNode* root)
{
	BinaryTreeNode* pcurNode=root;
	BinaryTreeNode* top=NULL;
	stack<BinaryTreeNode*> s;
	assert(root);
	while(pcurNode||!s.empty())
	{
		while(pcurNode)
		{
			s.push(pcurNode);
			pcurNode=pcurNode->_leftchild;
		}

		top=s.top();
		s.pop();
		printf("%d\n",top->_data);
		pcurNode=top->_rightchild;
	}
}
void PostOrder(BinaryTreeNode* root)
{
	stack<BinaryTreeNode*> s;
	BinaryTreeNode* pcurNode=root;
	BinaryTreeNode* top=NULL;
	BinaryTreeNode* pre=NULL;
	assert(root);
	while(pcurNode||!s.empty())
	{
		while(pcurNode)
		{
			s.push(pcurNode);
			pcurNode=pcurNode->_leftchild;
		}

		top=s.top();
		if(top->_rightchild==NULL||top->_rightchild==pre)
		{
			cout<<top->_data<<endl;
			pre=top;
			s.pop();
		}
		else
		{
			pcurNode=top->_rightchild;
			
		}
	}
}

下面我们实现层序遍历,层序遍历我用的是队列,当然我们以前做过一道题是用两个栈实现一个队列,所以这里我借用一下,可以用两个栈实现层序遍历
void LevelOrder_ByStack(BinaryTreeNode* root)
{
	stack<BinaryTreeNode*> stack_1;
	stack<BinaryTreeNode*> stack_2;
	BinaryTreeNode* pcurNode=NULL;
	stack_1.push(root);
	if(root!=NULL)
	{
		while(!stack_1.empty() || !stack_2.empty())
		{
			while(!stack_1.empty())
			{
				printf("%d\n",stack_1.top()->_data);
				stack_2.push(stack_1.top());
				stack_1.pop();
			}
			while(!stack_2.empty())
			{
				pcurNode=stack_2.top();
				if(pcurNode->_rightchild!=NULL)
					stack_1.push(pcurNode->_rightchild);
				if(pcurNode->_leftchild!=NULL)
					stack_1.push(pcurNode->_leftchild);
				
				stack_2.pop();
			}
		}
	}

}
void LevelOrder_ByQueue(BinaryTreeNode* root)
{
	BinaryTreeNode* pcurNode=NULL;
	queue<BinaryTreeNode*> q;
	assert(root);
	q.push(root);
	while(!q.empty())
	{
		pcurNode=q.front();
		printf("%d\n",pcurNode->_data);
		if(pcurNode->_leftchild)
		{
			q.push(pcurNode->_leftchild);
		}
		if(pcurNode->_rightchild)
		{
			q.push(pcurNode->_rightchild);
		}
		q.pop();
	}
}

递归实现求深度
int Depth(BinaryTreeNode* root,int &depth)
{
	if(root==NULL)
		return 0;
	int leftdepth=Depth(root->_leftchild,depth);
	int rightdepth=Depth(root->_rightchild,depth);
	return leftdepth>rightdepth?leftdepth+1:rightdepth+1;
}

递归实现求最远两个节点距离
int GetFastTwoNode(BinaryTreeNode* root,int &distance)
{
	if(root==NULL)
		return 0;
	int leftdepth=GetFastTwoNode(root->_leftchild,distance);
	int rightdepth=GetFastTwoNode(root->_rightchild,distance);
	if((leftdepth+rightdepth)>distance)
		distance=leftdepth+rightdepth;
	return leftdepth>rightdepth?leftdepth+1:rightdepth+1;
}
递归实现查找节点
BinaryTreeNode* FindNode(BinaryTreeNode* root,const int& key)
{
	if(root==NULL)
		return NULL;
	if(root->_data==key)
		return root;
	BinaryTreeNode* key_Node=FindNode(root->_leftchild,key);
	if(key_Node==NULL)
		key_Node=FindNode(root->_rightchild,key);
	return key_Node;


}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉树是一种非常重要的数据结构,它的基本操作包括创建、销毁、遍历、查找等。下面是二叉树基本操作的实现方法: 1. 创建二叉树:通过前序遍历的数组构建二叉树,其中 '#' 表示空节点。具体实现方法可以参考引用中的 BinaryTreeCreate 函数。 2. 销毁二叉树:遍历二叉树,依次释放每个节点的内存空间。具体实现方法可以参考引用中的 BinaryTreeDestory 函数。 3. 遍历二叉树二叉树的遍历包括前序遍历、中序遍历、后序遍历和层序遍历。具体实现方法可以参考引用中的 BinaryTreePrevOrder、BinaryTreeInOrder、BinaryTreePostOrder 和 BinaryTreeLevelOrder 函数。 4. 查找二叉树节点:在二叉树中查找值为 x 的节点,具体实现方法可以参考引用中的 BinaryTreeFind 函数。 5. 计算二叉树节点个数:计算二叉树中节点的个数,具体实现方法可以参考引用[2]中的 BinaryTreeSize 函数。 6. 计算二叉树叶子节点个数:计算二叉树中叶子节点的个数,具体实现方法可以参考引用中的 BinaryTreeLeafSize 函数。 7. 计算二叉树第 k 层节点个数:计算二叉树中第 k 层节点的个数,具体实现方法可以参考引用中的 BinaryTreeLevelKSize 函数。 8. 判断二叉树是否是完全二叉树:判断二叉树是否是完全二叉树,具体实现方法可以参考引用中的 BinaryTreeComplete 函数。 9. 计算二叉树的深度:计算二叉树的深度,具体实现方法可以参考引用中的 BinaryTreeDeep 函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值