二叉树及其遍历

一、前序遍历

void PreOrderRec(Btree* root)
{
	if (root == NULL)
	{
		return;
	}
	printf("- %d -", root->data);
	PreOrderRec(root->lchild);
	PreOrderRec(root->rchild);
}

二、(借助栈)前序遍历

void PreOrder(Btree* root)
{
	Bnode cur;
	if (root == NULL)
	{
		return;
	}
	SqStack stack;
	InitStack(stack);
	PushStack(stack, *root); //头节点先入栈
	while (!(IsEmpty(stack))) //栈为空,所有节点均已处理
	{
		PopStack(stack, cur); //要遍历的节点
		printf("- %d -", cur.data);
		if (cur.rchild != NULL)
		{
			PushStack(stack, *(cur.rchild)); //右子节点先入栈,后处理
		}
		if (cur.lchild != NULL)
		{
			PushStack(stack, *(cur.lchild)); //左子节点后入栈,接下来先处理
		}
	}
	DestroyStack(stack);
}

三、中序遍历

先访问根节点的左子树,然后访问根节点,最后遍历根节点的右子树

void PreOrderRec2(Btree *root)
{
	if(root == NULL)
		return ;

	PreOrderRec2(root->lchild);
	printf("-%d-",root->data);
	PreOrderRec2(root->rchild);	
	
} 

四、(借助栈)中序遍历

void PreOrder2(Btree* root)
{
	Bnode* cur = root;
	Bnode cur1;
	if(root == NULL)
		return  ;
		
	SqStack stack;
	
	InitStack(stack);

	while(!(IsEmpty(stack))|| cur!=NULL) 
	{
		while(cur!=NULL)
		{
			PushStack(stack,*cur);
			cur = cur->lchild;
		}

		PopStack(stack,cur1);//出栈 (根节点,记录器)  
		printf("-%d-",cur1.data);//打印出栈元素

		if(cur1.rchild!=NULL)
			cur = cur1.rchild;
	}
	DestroyStack(stack);	

}

 五、后序遍历

从左到右,先叶子后结点的方式遍历访问左右子树,最后访问根节点

void PreOrderRec3(Btree *root)
{
	if(root == NULL)
		return ;

	PreOrderRec3(root->lchild);
	PreOrderRec3(root->rchild);	
	printf("-%d-",root->data);
} 

删除结点

Btree* DeleteNode(Btree* root,int key, Bnode* &deletedNode)
{
		if(root==NULL)//没有找到删除节点 
			return NULL;
		
		if(root->data>key)//根节点的数据大于 要删除的节点,就往左子树上面找 
		{
			root->lchild = DeleteNode(root->lchild,key, deletedNode);//左子树的节点递归成新的根节点 
			return root;
		}
		if(root->data<key)//根节点的数据小于 要删除的节点,就往右子树上面找 
		{
			root->rchild = DeleteNode(root->rchild,key, deletedNode);//右子树的节点递归成新的根节点 
			return root;
		}
		
		deletedNode = root;//告诉main函数,被删除的是哪一个数据
		//走到这里说明已经找到了要删除的节点,此时的root就是目标节点 
		
		
		//删除节点不存在左右子节点,即为叶子节点,直接删除
		if(root->lchild==NULL&&root->rchild==NULL)
			return NULL;
		
		//删除节点只存在左子节点,直接用那个左子节点替代要删除的节点
		if(root->lchild!=NULL&&root->rchild==NULL)
			return root->lchild; 
			
		//删除节点只存在右子节点,直接用那个右子节点替代要删除的节点
		if(root->rchild!=NULL&&root->lchild==NULL)
			return root->rchild; 	
			
		//删除节点存在左右节点,直接用要删除节点的左子节点最大值或右子节点的最小值替代删除节点
		int val = findMax(root->lchild);      //	int val = findMax(root->rchild);	
		root->data = val;//用左子树上的最大节点 取代删除节点 
		root->lchild = DeleteNode(root->lchild,val, deletedNode);//递归把左子树的最大节点置空, 上面if(root->data<key)返回的root就是左子树的根节点 
		return root;
}

查找

/*非递归法查找*/ 
Bnode* queryByLoop(Btree* root,ElemType e)
{
	while(root!=NULL && !isEqual(root->data,e))
	{
		if(isLess(e,root->data))
			root = root->lchild;
		else
			root = root->rchild;
	}
	return root;
}
/*递归法查找*/
Bnode* queryByRec(Btree* root,ElemType e)
{
	if(root == NULL ||isEqual(root->data,e))//找不到该节点 || 找到了该节点   找到了直接返回目标节点到第一次调用该函数的地方 
		return root;
	else if(isLess(e,root->data))
		return queryByRec(root->lchild,e);
	else
		return queryByRec(root->rchild,e);
}

找出最大结点

int findMax(Btree* root)
{
	if(!root)
	{
		cout<<"finMax()函数报错!";
		return false;		
	}
	
	/*方式一:递归 
	if(root->rchild == NULL)
	{
		return root->data;
	}
	
	return findMax(root->rchild);
	*/
	
	/*方式二:循环*/
	 while(root->rchild)
	 {
	 	root = root->rchild;
	 }
	 
	 return root->data;
	 
}

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值