微软面试题,难度系数中下,题目描述如下:
题目:输入一颗二元查找树,将该树转换为它的镜像,
即在转换后的二元查找树中,左子树的结点都大于右子树的结点。
用递归和循环两种方法完成树的镜像转换。
例如输入:
8
/ \
6 10
/ \ / \
5 7 9 11
输出:
8
/ \
10 6
/ \ / \
11 9 7 5
逻辑分析:
1、之所以判定题目难度中下,原因在于这里要求用递归和非递归分别实现。我们知道,但凡是树的问题,大多递归可轻松解,本题也一样,仔细分析过后,没有多大难度,只是交换每一个节点的左右孩子而已。
我们定义二叉排序树节点:
typedef struct BSTreeNode //a node in the BST { int m_nValue; //Value of node struct BSTreeNode *m_pLeft; //left child of node struct BSTreeNode *m_pRight; //right child of node }BSTreeNode;
下面给出递归实现:
void ExchangeTree(BSTreeNode* root) { if(root) { ExchangeTree(root->m_pLeft); ExchangeTree(root->m_pRight); BSTreeNode* temp = root->m_pLeft; root->m_pLeft = root->m_pRight; root->m_pRight = temp; } }
非递归实现:
void ExchangeTree(BSTreeNode* root) { Stack S; InitialStack(&S); BSTreeNode *p = root; while(p != NULL || !isEmptyStack(&S)) { if(p != NULL) { BSTreeNode *temp = p->m_pLeft; p->m_pLeft = p->m_pRight; p->m_pRight = temp; Push(&S, p); p = p->m_pLeft; } else { BSTreeNode *temp = Pop(&S); p = temp->m_pRight; } } }
3、下面给出完整的代码实现,内置两种实现方式,匆忙写的,细节上可能仍然存在bug。
#include <stdio.h> typedef struct BSTreeNode //a node in the BST { int m_nValue; //Value of node struct BSTreeNode *m_pLeft; //left child of node struct BSTreeNode *m_pRight; //right child of node }BSTreeNode; /* void ExchangeTree(BSTreeNode* root) { if(root) { ExchangeTree(root->m_pLeft); ExchangeTree(root->m_pRight); BSTreeNode* temp = root->m_pLeft; root->m_pLeft = root->m_pRight; root->m_pRight = temp; } } */ typedef struct Stack { BSTreeNode* elem[100]; int top; int size; }Stack; void InitialStack(Stack* S) { S->top = 0; S->size = 0; } int isEmptyStack(Stack* S) { if(S->size == 0) return 1; else return 0; } void Push(Stack *S, BSTreeNode* node) { S->elem[S->top] = node; S->top++; S->size++; } BSTreeNode* Pop(Stack *S) { if(S->size == 0) return NULL; BSTreeNode* temp = S->elem[S->top-1]; S->top--; S->size--; return temp; } void ExchangeTree(BSTreeNode* root) { Stack S; InitialStack(&S); BSTreeNode *p = root; while(p != NULL || !isEmptyStack(&S)) { if(p != NULL) { BSTreeNode *temp = p->m_pLeft; p->m_pLeft = p->m_pRight; p->m_pRight = temp; Push(&S, p); p = p->m_pLeft; } else { BSTreeNode *temp = Pop(&S); p = temp->m_pRight; } } } void DLR(BSTreeNode* root) { if(root == NULL) return ; printf("%d\n",root->m_nValue); DLR(root->m_pLeft); DLR(root->m_pRight); } int main() { BSTreeNode node[7]; node[0].m_nValue = 8; node[0].m_pLeft = &node[1]; node[0].m_pRight = &node[2]; node[1].m_nValue = 6; node[1].m_pLeft = &node[3]; node[1].m_pRight = &node[4]; node[2].m_nValue = 10; node[2].m_pLeft = &node[5]; node[2].m_pRight = &node[6]; node[3].m_nValue = 5; node[3].m_pLeft = NULL; node[3].m_pRight = NULL; node[4].m_nValue = 7; node[4].m_pLeft = NULL; node[4].m_pRight = NULL; node[5].m_nValue = 9; node[5].m_pLeft = NULL; node[5].m_pRight = NULL; node[6].m_nValue = 11; node[6].m_pLeft = NULL; node[6].m_pRight = NULL; ExchangeTree(&node[0]); DLR(&node[0]); return 0; }
两种方式实现的结果图:
递归:
非递归: