数据结构和算法经典100题-第15题

题目:
输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换。
例如输入:
8
/ /
6 10
/ / / /
5 7 9 11

输出:
8
/ /
10 6
/ / / /
11 9 7 5


题目分析:

题目分析:

因为树的本质就是用递归实现的,所以用递归解决此问题并不难。就是有子树就翻转,那么上代码:

void BinaryTree::recursion(Node* obj) {
    // 交换左右子树
    swap(obj);

    if (NULL != obj->left) {
        recursion(obj->left);
    }

    if (NULL != obj->right) {
        recursion(obj->right);
    }

    return ;
}

// 递归实现
Node* BinaryTree::reverseWithRecursion() {
    recursion(m_root);
    return m_root;
}

递归向迭代转化。其实递归调用树的关键思想就是利用了函数的栈。我们可以自己建立一个栈,来模拟函数的栈。从而在函数即将递归的时候,压入我们的栈,然后弹出。我们还是看一下代码,代码是不会骗人的。

// 迭代实现
void BinaryTree::reverseWithIteration() {
    vector<Node*> stack;

    stack.push_back(m_root);
    Node* tmp = m_root;

    while (NULL != tmp) {
        // 把要交换的结点弹出栈
        stack.pop_back();
        swap(tmp);

        //
        if (NULL != tmp->left) {
            stack.push_back(tmp->left);
        }

        if (NULL != tmp->right) {
            stack.push_back(tmp->right);
        }

        if (0 < stack.size()) {
            tmp = stack.back();
        } else {
            break;
        }

    }

    return;
}

最后我们看一下完整的代码,首先我定义了一棵二叉树。

#ifndef ___00_alg_tests___5th__
#define ___00_alg_tests___5th__

#include <stdio.h>


struct Node {
    int value;
    Node* left;
    Node* right;
};

class BinaryTree {
    //递归
    void recursion(Node* obj);

    //
    void swap(Node* obj);

    // 树的根结点
    Node* m_root;

public:
    // 构造
    BinaryTree(Node* root) : m_root(root) {};

    // 析构
    ~BinaryTree() {};

    // 递归实现
    Node* reverseWithRecursion();

    // 迭代实现
    void reverseWithIteration();
};

int test_15();

#endif /* defined(___00_alg_tests___5th__) */
//
//  15th.cpp
//  100-alg-tests
//
//  Created by bobkentt on 15-5-10.
//  Copyright (c) 2015年 kedong. All rights reserved.
//

#include <vector>
#include <iostream>

#include "15th.h"

using namespace std;

/*
 题目:输入一颗二元查找树,将该树转换为它的镜像,
 即在转换后的二元查找树中,左子树的结点都大于右子树的结点。
 用递归和循环两种方法完成树的镜像转换。
 例如输入:
 8
 / /
 6  10
 / / / /
 5 7 9 11

 输出:
 8
 / /
 10  6
 / / / /
 11 9 7  5


 */

void BinaryTree::swap(Node* obj) {
    Node* tmp = obj->left;

    obj->left = obj->right;


    obj->right = tmp;

    return ;
}

void BinaryTree::recursion(Node* obj) {
    // 交换左右子树
    swap(obj);

    if (NULL != obj->left) {
        recursion(obj->left);
    }

    if (NULL != obj->right) {
        recursion(obj->right);
    }

    return ;
}

// 递归实现
Node* BinaryTree::reverseWithRecursion() {
    recursion(m_root);
    return m_root;
}

// 迭代实现
void BinaryTree::reverseWithIteration() {
    vector<Node*> stack;

    stack.push_back(m_root);
    Node* tmp = m_root;

    while (NULL != tmp) {
        // 把要交换的结点弹出栈
        stack.pop_back();
        swap(tmp);

        //
        if (NULL != tmp->left) {
            stack.push_back(tmp->left);
        }

        if (NULL != tmp->right) {
            stack.push_back(tmp->right);
        }

        if (0 < stack.size()) {
            tmp = stack.back();
        } else {
            break;
        }

    }

    return;
}

void Link(Node* obj, int parrent, int left, int right) {

    if (-1 != left) {
        obj[parrent].left = &obj[left];
    }

    if (-1 != right) {
        obj[parrent].right = &obj[right];
    }

    return ;
}

// 中序遍历打印树
void printTree(Node* obj)
{
    if (NULL != obj) {

        cout<<"Value = "<<obj->value<<endl;;
        printTree(obj->left);
        printTree(obj->right);

    } else {
        return ;
    }
}


int test_15()
{
/* tree like:

          0
        /    \
      1        2
     / \      / \
    3   4    5   6
   /          \
  7            8

    change into:
        0
    /      \
   2        1
  / \      / \
 6   5    4   3
    /          \
   8            7

*/



    Node obj_1[9];
    memset(obj_1, 0, sizeof(Node)*9);

    for (int i = 0; i < 9; i++) {
        obj_1[i].value = i;
        obj_1[i].left = NULL;
        obj_1[i].right = NULL;
    }

    Link(obj_1, 0, 1, 2);
    Link(obj_1, 1, 3, 4);
    Link(obj_1, 2, 5, 6);
    Link(obj_1, 3, 7, -1);
    Link(obj_1, 5, -1, 8);
    //printTree(&obj_1[0]);
    BinaryTree tree(&obj_1[0]);
    //Node* root = tree.reverseWithRecursion();
    tree.reverseWithIteration();
    printTree(&obj_1[0]);

    return 0;
}

测试结果:

Value = 0
Value = 2
Value = 6
Value = 5
Value = 8
Value = 1
Value = 4
Value = 3
Value = 7
Program ended with exit code: 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值