二叉树的部分总结,主函数在最下面,其中注明了有哪些二叉树的性质 ,所有的代码都是经过验证的均没有问题,只是代码格式需要调整。
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
#include<string>
#include<math.h>
using namespace std;
//创建树所使用的结构体
typedef struct BinaryTree
{
int val;
BinaryTree* lchild;
BinaryTree* rchild;
}binarytree,*BINARYTREE;
//创建二叉树
void creat_tree(BINARYTREE &root)
{
char ch;
ch = getchar();
if (ch == '#')
{
root = NULL;
}
else
{
root = new BinaryTree;
root->val = (ch-'0');
creat_tree(root->lchild);
creat_tree(root->rchild);
}
}
//层序遍历二叉树
BINARYTREE Sequence_travel(BINARYTREE root,int data)
{
if (root == NULL)
return root;
queue<BINARYTREE> que;
BINARYTREE p = NULL;
que.push(root);
while (!que.empty())
{
p = que.front();
if (p->val == data)
{
return p;
}
if (p->lchild != NULL)
{
que.push(p->lchild);
}
if (p->rchild != NULL)
{
que.push(p->rchild);
}
que.pop();
}
return NULL;
}
//前序遍历递归法
void Pre_Recursion(BINARYTREE root)
{
if (root == NULL)
return;
if (root != NULL)
{
cout << root->val << " ";
if (root->lchild != NULL)
{
Pre_Recursion(root->lchild);
}
if (root->rchild != NULL)
{
Pre_Recursion(root->rchild);
}
}
//cout << endl;
return;
}
//中序遍历递归法
void Mid_Recursion(BINARYTREE root)
{
if (root == NULL)
return;
if (root != NULL)
{
if (root->lchild != NULL)
{
Mid_Recursion(root->lchild);
}
cout << root->val << " ";
if (root->rchild != NULL)
{
Mid_Recursion(root->rchild);
}
}
return;
}
//后序遍历递归法
void Back_Recursion(BINARYTREE root)
{
if (root == NULL)
return;
if (root != NULL)
{
if (root->lchild != NULL)
{
Back_Recursion(root->lchild);
}
if (root->rchild != NULL)
{
Back_Recursion(root->rchild);
}
cout << root->val << " ";
}
return;
}
//前序遍历非递归法
void Pre_Not_Recursion(BINARYTREE root)
{
if (root == NULL)
return;
stack<BINARYTREE> sta;
BINARYTREE p = root;
while (!sta.empty() || p != NULL)
{
while (p)
{
cout << p->val << " ";
sta.push(p);
p = p->lchild;
}
if (!sta.empty())
{
p = sta.top();
sta.pop();
p = p->rchild;
}
}
return;
}
//中序遍历非递归法
void Mid_Not_Recursion(BINARYTREE root)
{
if (root == NULL)
return;
BINARYTREE p = root;
stack<BINARYTREE> sta;
while (!sta.empty() || p != NULL)
{
while (p)
{
sta.push(p);
p = p->lchild;
}
if (!sta.empty())
{
p = sta.top();
sta.pop();
cout << p->val << " ";
p = p->rchild;
}
}
return;
}
//后序遍历非递归法
void Back_Not_Recursion(BINARYTREE root)
{
if (root == NULL)
return;
stack<BINARYTREE> sta;
BINARYTREE cur, last_node;//一个表示当前值,一个表示最近刚访问的值
cur = root;
last_node = NULL;
while (cur)
{
sta.push(cur);
cur = cur->lchild;
}
while (!sta.empty())
{
cur = sta.top();
sta.pop();
//根节点被访问有两种情况,一种是没有右子数,另一种是右子树刚被访问
if (cur->rchild == NULL || cur->rchild == last_node)
{
cout << cur->val << " ";
last_node = cur;
}
else
{
//右子树要被访问则根节点需要再次入栈
sta.push(cur);
cur = cur->rchild;
while (cur)
{
sta.push(cur);
cur = cur->lchild;
}
}
}
return;
}
//二叉搜索树求公共祖先
void BinarySearchGetLastCommonAncestor(BINARYTREE root,BINARYTREE p,BINARYTREE q)
{
if (root == NULL || p == NULL || q == NULL)
{
cout << "不存在公共祖先" << endl;
return;
}
while (root != NULL)
{
if (root->val < p->val&&root->val < q->val)//p和q都在右子数
{
root = root->rchild;
}
else if (root->val > p->val&&root->val > q->val)//p和q都在左子数
{
root = root->lchild;
}
else
{
break;
}
}
cout << root->val << endl;
return;
}
//二叉树求公共祖先
BINARYTREE GetLastCommonAncestor(BINARYTREE root, BINARYTREE p, BINARYTREE q)
{
if (root == NULL || p == NULL || q == NULL)
{
return NULL;
}
if (p == root || q == root)
{
return root;
}
BINARYTREE left_node = GetLastCommonAncestor(root->lchild, p, q);
BINARYTREE right_node = GetLastCommonAncestor(root->rchild, p, q);
if (left_node&&right_node)
{
return root;
}
if (left_node == NULL)
{
return right_node;
}
else
{
return left_node;
}
}
//计算树的高度
int heigh(BINARYTREE root)
{
if (root == NULL)
return 0;
if (root->lchild == NULL&&root->rchild == NULL)
return 1;
return max(heigh(root->lchild), heigh(root->rchild)) + 1;
}
//二叉树节点最大距离
int TreeDistance(BINARYTREE root)
{
if (root == NULL)//节点为空,高度为0
return 0;
return max(heigh(root->lchild) + heigh(root->rchild) + 1, max(TreeDistance(root->lchild), TreeDistance(root->rchild)));
}
//打印双向链表
void print_two_list(BINARYTREE root)
{
BINARYTREE pre = NULL;
cout << "从前往后" << endl;
while (root != NULL)
{
pre = root;
cout << root->val << " ";
root = root->rchild;
}
cout << endl;
cout << "从后往前" << endl;
while (pre != NULL)
{
cout << pre->val << " ";
pre = pre->lchild;
}
cout << endl;
return;
}
//二叉树转双向链表的被调函数
void conver2list(BINARYTREE root, BINARYTREE &pointer)
{
if (root == NULL)
return;
if (root->lchild != NULL)
{
conver2list(root->lchild, pointer);
}
root->lchild = pointer;
if (pointer != NULL)
{
pointer->rchild = root;
}
pointer = root;
if (root->rchild != NULL)
{
conver2list(root->rchild, pointer);
}
}
//二叉树转双向链表
BINARYTREE conver(BINARYTREE root)
{
if (root == NULL)
return NULL;
BINARYTREE pointer = NULL;
conver2list(root, pointer);
while (pointer->lchild != NULL)
{
pointer = pointer->lchild;
}
return pointer;
}
//打印二叉树的所有路径
void print_binary_tree_all_path(vector<string> &res)
{
for (int i = 0; i < res.size(); i++)
{
cout << res[i] << endl;
}
return;
}
//二叉树所有路径的被调函数
void binaryTreePathsCore(BINARYTREE root, vector<string> &str, string strpath)
{
if (root == NULL)
{
return;
}
if (root->lchild == NULL&&root->rchild == NULL)
{
str.push_back(strpath);
return;
}
if (root->lchild != NULL)
{
binaryTreePathsCore(root->lchild, str, strpath + "->" + to_string(root->lchild->val));
}
if (root->rchild != NULL)
{
binaryTreePathsCore(root->rchild, str, strpath + "->" + to_string(root->rchild->val));
}
}
//二叉树的所有路径
vector<string> Binary_Tree_all_path(BINARYTREE root)
{
vector<string> result;
if (root == NULL)
return result;
binaryTreePathsCore(root, result, to_string(root->val));
return result;
}
//打印二叉树每层最大值
void print_per_layer_maxval(vector<int>&result)
{
if (result.size() == 0)
return;
cout << "每层的最大值" << endl;
for (int i = 0; i < result.size() - 1; i++)
{
cout << result[i] << " ";
}
cout << result[result.size() - 1] << endl;
return;
}
//二叉树每层的最大值
vector<int> binary_tree_per_layer_maxvalue(BinaryTree* root)
{
queue<BinaryTree*> que;
vector<int> result;
if (root == NULL)
return result;
que.push(root);
while (!que.empty())
{
int mid = que.size();
int max_val = INT_MIN;
for (int i = 0; i < mid; i++)
{
BinaryTree* node = que.front();
if (node->val > max_val)
max_val = node->val;
if (node->lchild)
que.push(node->lchild);
if (node->rchild)
que.push(node->rchild);
que.pop();
}
result.push_back(max_val);
}
return result;
}
//树的最大深度
int max_deepth(BINARYTREE root)
{
if (root == NULL)
return 0;
int leftDepth = max_deepth(root->lchild);
int rightDepth = max_deepth(root->rchild);
return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}
//树的最小深度
int min_deepth(BINARYTREE root)
{
if (root == NULL)
return 0;
if (root->lchild == NULL)
{
return min_deepth(root->rchild) + 1;
}
else if (root->rchild == NULL)
{
return min_deepth(root->lchild) + 1;
}
int leftDepth = min_deepth(root->lchild) + 1;
int rightDepth = min_deepth(root->rchild) + 1;
return leftDepth > rightDepth ? rightDepth : leftDepth;
}
//叶子节点的数量
void leaf_node_num(BINARYTREE root, int &k)
{
if (root == NULL)
return;
else
{
if (root->lchild == NULL&&root->rchild == NULL)
{
k++;
}
if (root->lchild)
{
leaf_node_num(root->lchild, k);
}
if (root->rchild)
{
leaf_node_num(root->rchild, k);
}
}
}
//判断二叉树是否为完全二叉树
bool IsComplete(BINARYTREE root)
{
if (root == NULL)
return false;
queue<BINARYTREE> que;
que.push(root);
while (!que.empty())
{
BINARYTREE p = que.front();
//如果该节点的两个孩子都在,则直接pop
if (p->lchild&&p->rchild)
{
que.pop();
que.push(p->lchild);
que.push(p->rchild);
}
//如果该节点的左孩子为空,右孩子不为空,则返回false
if (p->lchild == NULL&&p->rchild != NULL)
{
return false;
}
//如果左孩子不为空,右孩子为空或该节点为叶子节点,则该节点后面的节点都是叶子节点
if ((p->lchild&&p->rchild == NULL) || (p->lchild == NULL&&p->rchild == NULL))
{
que.pop();
//则该节点之后的所有节点都是叶子节点
while (!que.empty())
{
p = que.front();
if (p->lchild == NULL&&p->rchild == NULL)
{
que.pop();
}
else
{
return false;
}
}
return true;
}
}
return true;
}
//非递归求二叉树的深度
int deepth_not_recusion(BINARYTREE root)
{
queue<BINARYTREE>que;
if (root == NULL)
return 0;
que.push(root);
int result = 0;
while (!que.empty())
{
int len = que.size();
result++;
while (len--)
{
BINARYTREE temp = que.front();
que.pop();
if (temp->lchild)
que.push(temp->lchild);
if (temp->rchild)
que.push(temp->rchild);
}
}
return result;
}
//求一棵树的最大宽度
void getTreeMaxWidth(BINARYTREE root, int &height, int &width)
{
if (root == NULL)
{
height = 0;
width = 0;
}
int max_val = -1;
height = 0;
width = 0;
queue<BINARYTREE> que;
BINARYTREE p = NULL;
BINARYTREE q = root;
que.push(root);
while (!que.empty())
{
p = que.front();//返回队列中的第一个元素
width++;
if (p)
{
que.pop();
if (p->lchild)
que.push(p->lchild);
if (p->rchild)
que.push(p->rchild);
if (p == q)
{
if (!que.empty())
{
q = que.back();
}
height++;
if (width > max_val)
{
max_val = width;
width = 0;
}
}
}
}
width = max_val;
cout << width << endl;
}
int main(void)
{
/**************创建一棵二叉树***********/
注意:本例使用的创建树的方式为前序遍历的方式创建
例如:一棵树为:
则输入的时候按照前序遍历的方式输入,即:620##43##5##87##9##,其中#代表叶子节点0,3,5,7,9的左右孩子,其为空。
BinaryTree* root = NULL;
creat_tree(root);
/**************前序遍历递归法***********/
Pre_Recursion(root);
cout << endl;
/**************中序遍历递归法***********/
Mid_Recursion(root);
cout << endl;
/**************后序遍历递归法***********/
Back_Recursion(root);
cout << endl;
/**************前序遍历非递归法***********/
Pre_Not_Recursion(root);
cout << endl;
/**************中序遍历非递归法***********/
Mid_Not_Recursion(root);
cout << endl;
/**************后序遍历非递归法***********/
Back_Not_Recursion(root);
cout << endl;
/**************二叉搜索树最近公共祖先***********/
BINARYTREE p, q;
p = Sequence_travel(root, 6);
q = Sequence_travel(root, 6);
BinarySearchGetLastCommonAncestor(root, p, q);
/**************二叉树最近公共祖先***********/
BINARYTREE p1, q1, pq;
p1 = Sequence_travel(root, 0);
q1 = Sequence_travel(root, 9);
pq=GetLastCommonAncestor(root, p1, q1);
if (pq == NULL)
cout << "不存在公共祖先" << endl;
else
cout << "二叉树最近公共祖先:" << pq->val << endl;
/**************二叉树节点最大距离***********/
cout << "二叉树节点最大距离:" << TreeDistance(root) << endl;
/**************二叉树转双向链表***********/(注意:此项必须单独运行,因为已经转换为了双向链表就不具备二叉树的性质)
//BINARYTREE pq1;
//pq1=conver(root);
//print_two_list(pq1);
/**************二叉树的所有路径***********/
vector<string> all_path;
all_path=Binary_Tree_all_path(root);
print_binary_tree_all_path(all_path);
/**************二叉树每一层中最大值***********/
vector<int> max_value;
max_value = binary_tree_per_layer_maxvalue(root);
print_per_layer_maxval(max_value);
/**************二叉树最大深度***********/
cout << "二叉树最大深度:" << max_deepth(root) << endl;
/**************二叉树最小深度***********/
cout << "二叉树最小深度:" << min_deepth(root) << endl;
/**************二叉树深度非递归***********/
cout <<"二叉树深度:"<< deepth_not_recusion(root) <<endl;
/**************叶子节点的数量***********/
int k = 0;
leaf_node_num(root,k);
cout << "叶子节点数量:" << k << endl;
/**************判断一棵树是否为完全二叉树***********/
if (IsComplete(root))
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
/**************求一棵树的宽度***********/
int height, width;//定义树的高度和最大宽度
getTreeMaxWidth(root, height, width);
cout << "高度为:" << height << endl;
cout << "最大宽度为:" << width << endl;
return 0;
}