输入一颗二元查找树,将该树转换为它的镜像

来源:互联网 发布:php memcache redis 编辑:程序博客网 时间:2024/05/21 09:35

微软面试题,难度系数中下,题目描述如下:

题目:输入一颗二元查找树,将该树转换为它的镜像, 
即在转换后的二元查找树中,左子树的结点都大于右子树的结点。 
用递归和循环两种方法完成树的镜像转换。 
例如输入: 
          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;    }}


2、如果采用循环迭代,那么就非常类似二叉树非递归遍历,这里采用类似先序遍历的方式,借助一个辅助栈来实现,每一次完成交换左右孩子后,将当前的“根”节点入栈,然后向左进行循环交换,当左侧完结时,如果辅助栈中还有元素,那么取出来,将其右孩子作为下一次循环的起始点。当公交车指针p为空,且辅助栈也空时,交换完毕。

非递归实现:

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;}

两种方式实现的结果图:

递归:



非递归:


0 0
原创粉丝点击