【遍历二叉树】07恢复二叉搜索树【Recover Binary Search Tree】

开一个指针数组,中序遍历这个二叉搜索树,将节点的指针依次保存在数组里,

然后寻找两处逆序的位置,

中序便利里BST得到的是升序序列

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

二叉搜索树(BST)中的两个节点不小心被交换了下。

不改变其结构的情况下恢复这个树。

笔记:

用O(n)的空间复杂度的方法很直接。你能否设计一个常量空间的解决法方案?

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
test.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
 
#include <iostream>
#include <cstdio>
#include <stack>
#include <vector>
#include "BinaryTree.h"

using namespace std;


/**
 * Definition for binary tree
 * struct TreeNode {
 * int val;
 * TreeNode *left;
 * TreeNode *right;
 * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

vector<TreeNode *> inorderTraversal(TreeNode *root)
{
    stack<TreeNode *> s;
    vector<TreeNode *> path;
    TreeNode *p = root;
    while(p != NULL || !s.empty())
    {
        while(p != NULL)
        {
            s.push(p);
            p = p->left;
        }
        if(!s.empty())
        {
            p = s.top();
            path.push_back(p);
            s.pop();
            p = p->right;
        }
    }
    return path;
}

void recoverTree(TreeNode *root)
{
    vector<TreeNode *> inTrav = inorderTraversal(root);
    TreeNode *left, *right;
    int tmp;
    for (int i = 0; i < inTrav.size() - 1; ++i)
    {
        if (inTrav[i]->val > inTrav[i + 1]->val)
        {
            left = inTrav[i];
            break;
        }
    }
    for (int i = inTrav.size() - 1; i > 0; --i)
    {
        if (inTrav[i]->val < inTrav[i - 1]->val)
        {
            right = inTrav[i];
            break;
        }
    }
    tmp = left->val;
    left->val = right->val;
    right->val = tmp;
    return ;
}


// 树中结点含有分叉,
//                  6
//              /       \
//             7         2
//           /   \
//          1     4
//               / \
//              3   5
int main()
{
    TreeNode *pNodeA1 = CreateBinaryTreeNode(6);
    TreeNode *pNodeA2 = CreateBinaryTreeNode(7);
    TreeNode *pNodeA3 = CreateBinaryTreeNode(2);
    TreeNode *pNodeA4 = CreateBinaryTreeNode(1);
    TreeNode *pNodeA5 = CreateBinaryTreeNode(4);
    TreeNode *pNodeA6 = CreateBinaryTreeNode(3);
    TreeNode *pNodeA7 = CreateBinaryTreeNode(5);

    ConnectTreeNodes(pNodeA1, pNodeA2, pNodeA3);
    ConnectTreeNodes(pNodeA2, pNodeA4, pNodeA5);
    ConnectTreeNodes(pNodeA5, pNodeA6, pNodeA7);

    PrintTree(pNodeA1);

    cout << "before recover" << endl;
    vector<TreeNode *> ans = inorderTraversal(pNodeA1);

    for (int i = 0; i < ans.size(); ++i)
    {
        cout << ans[i]->val << " ";
    }
    cout << endl;

    recoverTree(pNodeA1);


    cout << "after recover" << endl;
    ans.clear();
    ans = inorderTraversal(pNodeA1);

    for (int i = 0; i < ans.size(); ++i)
    {
        cout << ans[i]->val << " ";
    }
    cout << endl;

    DestroyTree(pNodeA1);
    return 0;
}
输出结果:
before recover
1 7 3 4 5 6 2
after recover
1 2 3 4 5 6 7
BinaryTree.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
#ifndef _BINARY_TREE_H_
#define _BINARY_TREE_H_

struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};


TreeNode *CreateBinaryTreeNode(int value);
void ConnectTreeNodes(TreeNode *pParent,
                      TreeNode *pLeft, TreeNode *pRight);
void PrintTreeNode(TreeNode *pNode);
void PrintTree(TreeNode *pRoot);
void DestroyTree(TreeNode *pRoot);


#endif /*_BINARY_TREE_H_*/
BinaryTree.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
 
#include <iostream>
#include <cstdio>
#include "BinaryTree.h"

using namespace std;

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */


//创建结点
TreeNode *CreateBinaryTreeNode(int value)
{
    TreeNode *pNode = new TreeNode(value);

    return pNode;
}

//连接结点
void ConnectTreeNodes(TreeNode *pParent, TreeNode *pLeft, TreeNode *pRight)
{
    if(pParent != NULL)
    {
        pParent->left = pLeft;
        pParent->right = pRight;
    }
}

//打印节点内容以及左右子结点内容
void PrintTreeNode(TreeNode *pNode)
{
    if(pNode != NULL)
    {
        printf("value of this node is: %d\n", pNode->val);

        if(pNode->left != NULL)
            printf("value of its left child is: %d.\n", pNode->left->val);
        else
            printf("left child is null.\n");

        if(pNode->right != NULL)
            printf("value of its right child is: %d.\n", pNode->right->val);
        else
            printf("right child is null.\n");
    }
    else
    {
        printf("this node is null.\n");
    }

    printf("\n");
}

//前序遍历递归方法打印结点内容
void PrintTree(TreeNode *pRoot)
{
    PrintTreeNode(pRoot);

    if(pRoot != NULL)
    {
        if(pRoot->left != NULL)
            PrintTree(pRoot->left);

        if(pRoot->right != NULL)
            PrintTree(pRoot->right);
    }
}

void DestroyTree(TreeNode *pRoot)
{
    if(pRoot != NULL)
    {
        TreeNode *pLeft = pRoot->left;
        TreeNode *pRight = pRoot->right;

        delete pRoot;
        pRoot = NULL;

        DestroyTree(pLeft);
        DestroyTree(pRight);
    }
}



 
 
 
 
 
 
 
 
posted @ 2014-04-08 16:45  z陵  阅读(202)  评论(0编辑  收藏  举报