树的常考题

这篇博客介绍了几种二叉树的操作,包括:1)如何将二叉树转换为其镜像;2)判断一棵树是否是另一棵树的子结构;3)有序二叉树转双向链表;4)在有序二叉树中找到倒数第K个大的数;5)检查二叉树是否对称;6)按照之字形打印二叉树的方法。这些算法通过递归和栈实现了二叉树的各种变换和遍历。
摘要由CSDN通过智能技术生成

1、把一棵二叉树转换为它的镜像树

void mirror_tree(TreeNode* root)
{
	if(NULL == root) return;
	
	TreeNode* temp = root->left;
	root->left = root->right;
	root->right = temp;

	mirror_tree(root->left);
	mirror_tree(root->right);
}

2、输入两棵二叉树A,B,判断B是不是A的子结构(我们约定空树不是任意一个树的子结构)

//	比较两个树r2 是否是 r1
bool _cmp_tree(TreeNode* r1,TreeNode* r2)
{
	if(NULL == r1 && NULL == r2) return true;
	if(NULL == r1 && NULL != r2) return false;
	if(NULL != r1 && NULL == r2) return true;

	if(r1->data != r2->data) return false;
	return _cmp_tree(r1->left,r2->left) &&
	_cmp_tree(r1->right,r2->right);
}

//	子结构
bool is_subtree(TreeNode* A,TreeNode* B)
{
	if(NULL == A) return false;

	if(A->data == B->data)
	{
		bool flag = _cmp_tree(A,B);
		if(flag) return flag;
	}
	bool lflag = is_subtree(A->left,B);
	bool rflag = is_subtree(A->right,B);
	return lflag || rflag;
}

3、将一棵有序二叉树转换成一个有序的双向链表

//	尾添加到链表
void __add_tail_list(TreeNode** head,TreeNode* node)
{
	if(NULL == *head)
	{
		*head = node;	
	}
	else
	{
		(*head)->left->right = node;
		node->left = (*head)->left;
	}
	(*head)->left = node;
}

void _tree_to_list(TreeNode* root,TreeNode** head)
{
	if(NULL == root) return;
	//	按照中序转换链表
	_tree_to_list(root->left,head);
	//	根节点尾添加到链表
	__add_tail_list(head,root);	
	_tree_to_list(root->right,head);
}
//	转换双向链表
TreeNode* tree_to_list(TreeNode* root)
{
	TreeNode* head = NULL;
	_tree_to_list(root,&head);
	//	最后一个节点的right需要指向head,才能形成循环
	//	但是在__add_tail_list 不能让最后一个节点的right指向head,因为需要它去遍历右子树
	head->left->right = head;
	return head;
}

4、计算出有序二叉树中倒数第K个大的数

bool _access_tree(TreeNode* root,int* cnt,size_t index,int* ptr)
{
	if(NULL == root) return false;
	bool rflag =  _access_tree(root->right,cnt,index,ptr);
	if(rflag) return true;
	if((*cnt)++ == index)
	{
		*ptr = root->data;
		return true;
	}
	return _access_tree(root->left,cnt,index,ptr);
}

//	按中序进行访问
bool access_tree(TreeNode* root,size_t index,int* ptr)
{
	int cnt = 0;
	return _access_tree(root,&cnt,index,ptr);
}

5、判断一个二叉树是否对称

//	判断r1 r2 是否完全对称
bool _is_sym(TreeNode* r1,TreeNode* r2)
{
	if(NULL == r1 && NULL == r2) return true;
	if(NULL == r1 && NULL != r2) return false;
	if(NULL != r1 && NULL == r2) return false;
	if(r1->data != r2->data) 	 return false;

	bool lflag = _is_sym(r1->left,r2->right);
	bool rflag = _is_sym(r1->right,r2->left);
	return lflag && rflag;
}

//	对称
bool is_sym_tree(TreeNode* root)
{
	if(NULL == root) return true;
	return _is_sym(root->left,root->right);
}

6、请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推

void Z_show_tree(TreeNode* root)
{
	ListStack* s1 = create_list_stack();
	ListStack* s2 = create_list_stack();
	push_list_stack(s1,root);

	while(!empty_list_stack(s1) || !empty_list_stack(s2))
	{
		while(!empty_list_stack(s1))
		{
			//s1入s2  从左到右入
			TreeNode* top = top_list_stack(s1);
			pop_list_stack(s1);
			if(top->left) push_list_stack(s2,top->left);
			if(top->right) push_list_stack(s2,top->right);
			printf("%d ",top->data);
		}

		while(!empty_list_stack(s2))
		{
			// s2入s1  从右到左入
			TreeNode* top = top_list_stack(s2);
			pop_list_stack(s2);
			if(top->right) push_list_stack(s1,top->right);
			if(top->left) push_list_stack(s1,top->left);
			printf("%d ",top->data);
		}
	}
	destroy_list_stack(s1);
	destroy_list_stack(s2);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值