二叉树的问题
1.二叉树三种周游(traversal)方式:
二叉树的问题
1.二叉树三种周游(traversal)方式:
2.怎样从顶部开始逐层打印二叉树结点数据
3.如何判断一棵二叉树是否是平衡二叉树
4.设计一个算法,找出二叉树上任意两个节点的最近共同父结点,复杂度如果是O(n2)则不得分。
5.如何不用递归实现二叉树的前序/后序/中序遍历?
6.在二叉树中找出和为某一值的所有路径
7.怎样编写一个程序,把一个有序整数数组放到二叉树中?
8.判断整数序列是不是二叉搜索树的后序遍历结果
9.求二叉树的镜像
10.一棵排序二叉树(即二叉搜索树BST),令 f=(最大值+最小值)/2,设计一个算法,找出距离f值最近、大于f值的结点。复杂度如果是O(n2)则不得分。
11.把二叉搜索树转变成排序的双向链表
12.打印二叉树中的所有路径(与题目5很相似)
#include <iostream>
#include <vector>
#include <map>
#include <list>
using namespace std;
typedef struct TreeNode {
int data;
TreeNode* left;
TreeNode* right;
TreeNode* parent;
} *Node;
/************************************************************************/
/* 10
8 15
6 9 13
12
*/
/************************************************************************/
Node createTree()
{
Node root = new TreeNode();
root->data = 10;
root->left = root->right = root->parent = NULL;
//左子树
Node left = new TreeNode();
left->data = 8;
left->left = left->right = left->parent = NULL;
//左子树的左子树
Node left_left = new TreeNode();
left_left->data = 6;
left_left->left = left_left->right = left_left->parent = NULL;
//左子树的右子树
Node left_right = new TreeNode();
left_right->data = 9;
left_right->left = left_right->right = left_right->parent = NULL;
left->left = left_left;
left->right = left_right;
left_right->parent = left;
left_left->parent = left;
//右子树
Node right = new TreeNode();
right->data = 15;
right->left = right->right = right->parent = NULL;
//右子树的左子树
Node right_left = new TreeNode();
right_left->data = 13;
right_left->left = right_left->right = right_left->parent = NULL;
//右子树的左子树的左子树
Node right_left_left = new TreeNode();
right_left_left->data = 12;
right_left_left->left = right_left_left->right = right_left_left->parent = NULL;
right_left->left = right_left_left;
right_left_left->parent = right_left;
right->left = right_left;
right_left->parent = right;
root->left = left;
root->right = right;
left->parent = root;
right->parent = root;
return root;
}
//递归前序遍历
void PreOrderTraverse(Node root)
{
if (!root) return;
cout << root->data <<" ";
PreOrderTraverse(root->left);
PreOrderTraverse(root->right);
}
//非递归前序遍历
void Not_Recursion_PreOrderTraverse(Node root)
{
if (!root) return;
Node node = root;
vector<Node> v;
while (node || v.size())
{
while (node)
{
cout << node->data << " ";
v.push_back(node);
node = node->left;
}
if (v.size())
{
node = v.back();
v.pop_back();
node = node->right;
}
}
}
//中序遍历
void InOrderTraverse(Node root)
{
if (!root) return;
InOrderTraverse(root->left);
cout << root->data << " ";
InOrderTraverse(root->right);
}
//非递归中序遍历
void Not_Recursion_InOrderTraverse(Node root)
{
if (!root) return;
Node node = root;
vector<Node> v;
while (node || v.size())
{
while (node)
{
v.push_back(node);
node = node->left;
}
if (v.size())
{
node = v.back();
v.pop_back();
cout << node->data <<" ";
node = node->right;
}
}
}
//后序遍历
void PostOrderTraverse(Node root)
{
if (!root) return;
PostOrderTraverse(root->left);
PostOrderTraverse(root->right);
cout << root->data <<" ";
}
//非递归后序遍历
void Not_Recursion_PostOrderTraverse(Node root)
{
if (!root) return;
Node node = root;
vector<Node> v;
std::map<Node, int> map;
while (node || v.size())
{
while (node)
{
v.push_back(node);
map[node] = 0;
node = node->left;
}
if (v.size())
{
node = v.back();
if (!node->right || map[node])
{
cout << node->data <<" ";
v.pop_back();
if (map[node])
{
map[node] = NULL;
node = NULL;
continue;
}
map[node] = NULL;
}
map[node] = 1;
node = node->right;
}
}
}
//层次打印树
void Level_Tree_Print(Node root)
{
if (!root) return;
Node node = root;
list<Node> v;
v.push_back(node);
while(v.size())
{
Node treeNode = v.front();
v.pop_front();
cout << treeNode->data << " ";
if (treeNode->left) v.push_back(treeNode->left);
if (treeNode->right) v.push_back(treeNode->right);
}
}
//获取指定子树的高度
int TreeDepth(Node root)
{
if (!root) return 0;
Node node = root;
int depth = 0;
int left_depth = TreeDepth(root->left);
int right_depth = TreeDepth(root->right);
depth = left_depth > right_depth ? left_depth + 1 : right_depth + 1;
return depth;
}
// 判断树是否是平衡二叉树
bool is_balance_tree(Node root)
{
if (!root) return true;
bool flag = false;
int left_depth = TreeDepth(root->left);
int right_depth = TreeDepth(root->right);
if (abs(left_depth - right_depth) < 2)
flag = true;
bool left = is_balance_tree(root->left);
bool right = is_balance_tree(root->right);
return flag && left && right;
}
//二叉树的镜像
Node tree_photo(Node root)
{
if (!root) return NULL;
Node node = root->left;
root->left = root->right;
root->right = node;
tree_photo(root->left);
tree_photo(root->right);
return root;
}
// 找出从根节点到叶子节点的所有路径
vector<Node> v;
void print_vector(vector<Node> v)
{
for (vector<Node>::iterator iter = v.begin(); iter != v.end(); iter++)
cout << ((Node)(*iter))->data << " ";
cout <<endl;
}
void tree_path(Node root)
{
if (!root) return;
v.push_back(root);
if (!root->left && !root->right)
{
print_vector(v);
v.pop_back();
return;
}
tree_path(root->left);
tree_path(root->right);
v.pop_back();
}
//一棵排序二叉树(即二叉搜索树BST),令 f=(最大值+最小值)/2,设计一个算法,找出距离f值最近、大于f值的结点
Node find_f(Node root)
{
if (!root) return NULL;
int min, max;
Node node = root;
while (node->left) node = node->left;
min = node->data;
node = root;
while(node->right) node = node->right;
max = node->data;
int f = (min + max) / 2;
node = root;
Node previous = node;
while (node)
{
if ( f >= node->data )
{
node = node->right;
}
else
{
previous = node;
node = node->left;
}
}
return previous;
}
//把二叉树转换成双向链表
Node tree_to_link(Node root)
{
if (!root) return NULL;
Node node = root;
vector<Node> v;
Node head = root;
while (node)
{
head = node;
node = node->left;
}
node = root;
Node previous = NULL;
while (node || v.size())
{
while (node)
{
v.push_back(node);
node = node->left;
}
if (v.size())
{
node = v.back();
v.pop_back();
if (previous)
previous->right = node;
node->left = previous;
previous = node;
node = node->right;
}
}
return head;
}
//判断给定的序列是否是二叉树的后续遍历
bool isPostOrderTraverse(int a[], int begin, int end)
{
if (begin >= end)
return 1;
else
{
int location = begin;
for (int i = begin; i < end; i++)
{
if (a[i] > a[end])
{
location = i;
break;
}
}
if (a[i-1] < a[end]) location = i;//判断是否是break跳出来的,否则更新location
for (i = location; i < end; i++)
if (a[i] < a[end])
return 0;
bool lflag = isPostOrderTraverse(a, begin, location-1);
bool rflag = isPostOrderTraverse(a, location, end-1);
if (lflag && rflag)
return 1;
else
return 0;
}
}
//怎样编写一个程序,把一个有序整数数组放到二叉树中?
void createTreeFromArray(int a[], int begin, int end, treeNode** root){
if (begin > end)
return;
else{
*root = (treeNode*) malloc(sizeof(treeNode));
int mid = (begin + end) / 2;
(*root)->data = a[mid];
(*root)->rchild = NULL;
(*root)->lchild = NULL;
createTreeFromArray(a, begin ,mid - 1, &(*root)->lchild);
createTreeFromArray(a, mid + 1 ,end, &(*root)->rchild);
}
}
void main()
{
Node root = createTree();
cout << "先序遍历:" ;
PreOrderTraverse(root);
cout <<endl;
cout << "非递归先序遍历:";
Not_Recursion_PreOrderTraverse(root);
cout << endl;
cout << "中序遍历:" ;
InOrderTraverse(root);
cout <<endl;
cout << "非递归中序遍历:";
Not_Recursion_InOrderTraverse(root);
cout <<endl;
cout << "后序遍历:" ;
PostOrderTraverse(root);
cout <<endl;
cout << "非递归后序遍历:" ;
Not_Recursion_PostOrderTraverse(root);
cout <<endl;
cout << "树的层次打印:" ;
Level_Tree_Print(root);
cout <<endl;
cout << "树的高度:";
cout << TreeDepth(root);
cout <<endl;
if (is_balance_tree(root->right)) cout << "是平衡二叉树" <<endl;
else cout << "不是平衡二叉树" <<endl;
cout << "树的路径所有路径:" <<endl;
tree_path(root);
cout << find_f(root)->data <<endl;
cout << "树转换成双向链表后:";
Node node = tree_to_link(root);
while (node)
{
cout << node->data << " ";
node = node->right;
}
cout <<endl;
cout << "判断给定数组是否是二叉树后序遍历结果:";
int a[] = {6,9,8,12,13,15,10};
if (isPostOrderTraverse(a, 0, 6))
cout << " 是" <<endl;
else cout << " 否" <<endl;
}