输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点

输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。

例如给定下列的输入:


然后有如下的输出:


可以看到,所谓树的镜像,就是把同一层中属于同一个父节点的两个子节点进行对调。图中没有给出一个父节点之后一个子节点的情况,但是可以把问题统一于一个父节点同时存在两个左右子节点的情况,这两个子节点可以同时存在,但是其中一个也可以是空,可以把NULL当做父节点的一个子节点,在交换后不会有影响。

这个题目可以应用递归和栈这两种方法都是一样的,因为递归本身就是用的栈的原理。

1,递归:


首先交换8的两个子节点,然后得到上面的情况,看到节点10,6的子节点还是原来的序列,所以递归的调用方法进行对调,直到节点和节点的左右子树都为空为止。

2,应用栈的原理,首先把8压栈。然后开始操作栈,如果栈不空,就弹出栈中的元素,并交换元素的左右两个子节点。如果这两个节点分别处理,如果不空,然后压入栈中,压栈操作完后,再对栈进行操作。代码如下:

#include<iostream>
#include<stack>
using namespace std;

typedef struct BSTNode{
	int data;
	struct BSTNode *lchild;
	struct BSTNode *rchild;
}BSTNode,*BSTTree;
bool search_tree(BSTTree T, BSTNode *parent, BSTNode **p, int key) {
	if(!T) {
		*p = parent;
		return false;
	}
	if(T->data == key) {
		*p = T;
		return true;
	}else if(key < T->data)
		return search_tree(T->lchild, T, p, key);
	else
		return search_tree(T->rchild, T, p, key);
}
bool insert_tree(BSTTree *T, int key) {
	BSTNode *p = NULL;
	if(!search_tree(*T, NULL, &p, key)){
		BSTNode *temp = (BSTNode*)malloc(sizeof(BSTNode));
		temp->data = key;
		temp->lchild = NULL;
		temp->rchild = NULL;
		if(!(*T))
			*T = temp;
		else if(key < p->data)
			p->lchild = temp;
		else
			p->rchild = temp;
		return true;
	}
	return false;
}
void traverse_tree(BSTTree T) {
	if(T) {
		traverse_tree(T->lchild);
		printf("%d\t",T->data);
		traverse_tree(T->rchild);
	}
}
void mirror_tree(BSTTree T) {
	if(T) {
		mirror_tree(T->lchild);
		mirror_tree(T->rchild);
		BSTNode *temp;
		temp = T->lchild;
		T->lchild = T->rchild;
		T->rchild = temp;
	}
}
void mirror_by_stack(BSTTree T){
	stack<BSTNode*> m_stack;
	if(!T)
		m_stack.push(T);
	while(!m_stack.empty()){
		BSTNode *p = m_stack.top();
		m_stack.pop();

		BSTNode *temp;
		temp = p->lchild;
		p->lchild = p->rchild;
		p->rchild = temp;
		
		if(p->lchild)
			m_stack.push(p->lchild);
		if(p->rchild)
			m_stack.push(p->rchild);
	}
}
void main() {
	BSTTree T = NULL;
	if(insert_tree(&T, 8))
		printf("ok\n");
	if(insert_tree(&T, 6))
		printf("ok\n");
	if(insert_tree(&T, 10))
		printf("ok\n");
	if(insert_tree(&T, 5))
		printf("ok\n");
	if(insert_tree(&T, 7))
		printf("ok\n");
	if(insert_tree(&T, 9))
		printf("ok\n");
	if(insert_tree(&T, 11))
		printf("ok\n");
	traverse_tree(T);
	printf("\n");

	mirror_tree(T);
	traverse_tree(T);
	printf("\n");

	mirror_by_stack(T);
	traverse_tree(T);
	printf("\n");
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值