【遍历二叉树】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); } } |