1.求二叉树中最远的两个节点的距离;即求宽度
2.由前序遍历和中序遍历重建二叉树
3.将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向;
4.判断一颗二叉树是否是另一颗树的子树。
BinaryTree.h 实现
//#pragma once
#ifndef _BINARYTREE_H
#define _BINARYTREE_H
#include<iostream>
#include<queue>
#include<stack>
#include<deque>
using namespace std;
template <class T>
class BinTreeNode
{
public:
BinTreeNode() :left(NULL), right(NULL) {}
BinTreeNode(T v) :left(NULL), right(NULL), data(v) {}
~BinTreeNode(){}
public:
T data;
BinTreeNode<T> *left, *right;
};
template <class T>
class BinaryTree
{
public:
BinaryTree() :root(NULL), flag('#') {}
BinaryTree(T v) :root(NULL),flag(v) {}
public:
void CreateBinTree(const T *&str)
{
CreateBinTree(root, str);
}
//已知前序和中序遍历创建树
void CreateBinTree_VLR_LVR(const char *vlr, const char *lvr)
{
int n = strlen(vlr);
root = CreateBinTree_VLR_LVR(vlr, lvr, n);
}
//同理有已知后续和中序创建树
void CreateBinTree_LVR_LRV(const char *lvr,const int *lrv){}
//树的叶子结点数
int LeafSize()const { return LeafSize(root); }
//树的结点数
int size() { return size(root); }
//树的高度
int height() { return height(root); }
//树的高度
int Weight() { return Weight(root); }
/*********************采用递归*********************************************/
void PreOrder() const{PreOrder(root);}//前序遍历
void InOrder()const {InOrder(root);}//中序遍历
void PostOrder()const {PostOrder(root);}//后序遍历
void LeveLOrder() const { LeveLOrder(root); }//层遍历
/*********************采用非递归*******************************************/
void Non_Recursive_PreOrder()const { Non_Recursive_PreOrder(root); }
void Non_Recursive_InOrder() const { Non_Recursive_InOrder(root); }
void Non_Recursive_PostOrder()const { Non_Recursive_PostOrder(root); }
/*************************************************************************/
//判断一个颗树是否是树的子树
bool Equal_Is_Subtree(BinaryTree<T> &bt)
{
BinTreeNode<T> *tmp= Find(bt.root->data);
return Equal(tmp, bt.root);
}
//判断两个二叉树是否相等
bool Equal(BinaryTree<T> &bt)
{
return Equal(root, bt.root);
}
//将二叉树转换成双向循环链表
BinTreeNode<T>* ConvertList()
{
return ConvertList(root);
}
//判断值是否存在在节点中
bool IsInTree(const T&key)
{
return IsInTree(root, key);
}
//交换左右子数
void SwapLeftRightChild() { SwapLeftRightChild(root); }
//求两个结点的最近的父节点
BinTreeNode<T>* CommonParent(const T &x, const T &y)
{
BinTreeNode<T> *px = Find(root, x);
BinTreeNode<T> *py = Find(root, y);
if (px == NULL || py == NULL)
{
return NULL;
}
return CommonParent(root, px, py);
}
//查找结点
BinTreeNode<T>* Find(const T &key)
{
return Find(root, key);
}
//求一个结点的父结点
BinTreeNode<T>*Parent(const T &key)
{
BinTreeNode<T> *p = Find(root, key);
if (p == NULL)
return NULL;
return Parent(root, p);
}
protected:
bool Equal(BinTreeNode<T> *t1,BinTreeNode<T> *t2)
{
if (t1 == NULL && t2 == NULL)
return true;
else if ((t1 != NULL && t2 != NULL)
&& (t1->data == t2->data)
&& Equal(t1->left, t2->left)
&& Equal(t1->right, t2->right))
return true;
return false;
}
void ConvertList_InOrder(queue<BinTreeNode<T> *> &q, BinTreeNode<T> *t)
{
if (t != NULL)
{
ConvertList_InOrder(q,t->left);
//先应用一个队列把前序遍历结点的地址存放
q.push(t);
ConvertList_InOrder(q,t->right);
}
}
BinTreeNode<T>* ConvertList(BinTreeNode<T> *t)
{
queue<BinTreeNode<T> *> Q;
//调用上面的函数进行结点地址的获取
ConvertList_InOrder(Q, t);
BinTreeNode<T> *head=NULL,*p=NULL,*s;//定义链表的头,p指向头,s指向新出来的结点
if (!Q.empty())//先让头结点等于第一个出队的结点
{
head = Q.front();
Q.pop();
head->left = NULL;
p = head;
}
while (!Q.empty())//如果队列不空即还有元素
{
s = Q.front();
Q.pop();
p->right = s;//rigt相当于链表的next
s->left = p;//left相当于链表的pre
p = s;//p移到s
}
p->right = NULL;
return head;
}
BinTreeNode<T>* CreateBinTree_VLR_LVR(const char *vlr, const char *lvr, int n)
{
if (n == 0)
return NULL;
int k = 0;
while (vlr[0] != lvr[k])
k++;
BinTreeNode<T> *t = new BinTreeNode<T>(vlr[0]);
t->left = CreateBinTree_VLR_LVR(vlr+1,lvr,k);
t->right = CreateBinTree_VLR_LVR(vlr+k+1,lvr+k+1,n-k-1);
return t;
}
int Weight(BinTreeNode<T> *t)const
{
if (t == NULL)
return 0;
deque<BinTreeNode<T> *> Q1, Q2;
Q1.push_back(t);
int max_weight = 1;
int tmp_weight = 0;
BinTreeNode<T> *p;
while (!Q1.empty())
{
while (!Q1.empty())
{
p = Q1.front();
Q1.pop_front();
if (p->left != NULL)
Q2.push_back(p->left);
if (p->right != NULL)
Q2.push_back(p->right);
}
tmp_weight = Q2.size();
if (tmp_weight > max_weight)
max_weight = tmp_weight;
Q1 = Q2;
Q2.clear();
}
return max_weight;
}
int LeafSize(BinTreeNode<T> *t)const
{
if (t == NULL)
return 0;
if (t->left == NULL && t->right == NULL)
return 1;
else
return LeafSize(t->right) + LeafSize(t->right);
}
int size(BinTreeNode<T> *t )
{
if (t == NULL)
return 0;
else
return size(t->left) + size(t->right) + 1;
}
int height(BinTreeNode<T> *root)
{
if (root == NULL)
return 0;
else
{
int m = height(root->left);
int n = height(root->right);
return (m > n ? m : n) + 1;
}
}
BinTreeNode<T>* CommonParent(BinTreeNode<T>*t, BinTreeNode<T> *x, BinTreeNode<T> *y)
{
if (t == NULL)
return NULL;
if (IsInTree(x, y->data))return x;
if (IsInTree(y, x->data))return y;
BinTreeNode<T> *left, *right, *another_left, *another_right;
left = IsInTree(t->left, x->data);
right = IsInTree(t->right, y->data);
another_left = IsInTree(t->left, y->data);
another_right = IsInTree(t->right, x->data);
if ((left&&right) || (another_right&&another_left))
return t;
else if (left&&another_left)
return CommonParent(t->left, x, y);
else if (right &&another_right)
return CommonParent(t->right, x, y);
else
return NULL;
}
BinTreeNode<T>* Find(BinTreeNode<T> *t, const T &key)
{
if (t == NULL)
return NULL;
if (t->data == key)
return t;
BinTreeNode<T> *p = Find(t->left, key);
if (p != NULL)
return p;
p = Find(t->right, key);
return p;
}
BinTreeNode<T>*Parent(BinTreeNode<T> *t,BinTreeNode<T> *p)
{
if (t == NULL||p==t)
return NULL;
if (t->left == p || t->right == p)
return t;
else
{
BinTreeNode<T> *tmp = Parent(t->left,p);
if (tmp != NULL)
return tmp;
return Parent(t->right, p);
}
}
BinTreeNode<T>* IsInTree(BinTreeNode<T> *t, const T &key)
{
BinTreeNode<T>*p = Find(t, key);
if (p != NULL)
return p;
else
return NULL;
}
void SwapLeftRightChild(BinTreeNode<T> *&t)
{
if (t == NULL || (t->left == NULL && t->right == NULL))
return;
BinTreeNode<T> *ptmp = t->left;
t->left = t->right;
t->right = ptmp;
SwapLeftRightChild(t->left);
SwapLeftRightChild(t->right);
}
//////////////////////////////////////////////////////////////////////////
void Non_Recursive_PreOrder(BinTreeNode<T> *t)const
{
if (t != NULL)
{
stack<BinTreeNode<T> *> s;
s.push(t);
BinTreeNode<T> *p;
while (!s.empty())
{
p = s.top();
s.pop();
cout << p->data << " ";
if (p->right != NULL)
s.push(p->right);
if (p->left != NULL)
s.push(p->left);
}
}
}
void Non_Recursive_InOrder(BinTreeNode<T> *t)const
{
stack<BinTreeNode<T> *>s;
BinTreeNode<T> *temp = t;
while (temp || !s.empty())
{
while (temp) //有右边就要右边左子树入栈
{
s.push(temp);
temp = temp->left;
}
temp = s.top();
cout << temp->data << " ";
s.pop();
temp = temp->right;
}
}
void Non_Recursive_PostOrder(BinTreeNode<T> *t)const
{
stack<BinTreeNode<T> *>s;
BinTreeNode<T> *temp = root, *pre = NULL;
while (temp || !s.empty())
{
while (temp)
{
s.push(temp);
temp = temp->left;
}
temp = s.top();
if (!temp->right || temp->right == pre)//判断无右边
{
cout << temp->data << " ";
s.pop();
pre = temp;
temp = NULL;
}
else
temp = temp->right;
}
}
///////////////////////////////////////////////////////////////////////////
void LeveLOrder(BinTreeNode<T> *t)const
{
if (t != NULL)
{
queue<BinTreeNode<T>*> Q;
BinTreeNode<T> *p;
Q.push(t);
while (!Q.empty())
{
p = Q.front();
Q.pop();
cout << p->data << " ";
if (p->left != NULL)
Q.push(p->left);
if (p->right != NULL)
Q.push(p->right);
}
}
}
void PreOrder(BinTreeNode<T> *t)const
{
if (t != NULL)
{
cout << t->data << " ";
PreOrder(t->left);
PreOrder(t->right);
}
}
void InOrder(BinTreeNode<T> *t)const
{
if (t != NULL)
{
InOrder(t->left);
cout << t->data << " ";
InOrder(t->right);
}
}
void PostOrder(BinTreeNode<T> *t)const
{
if (t != NULL)
{
PostOrder(t->left);
PostOrder(t->right);
cout << t->data << " ";
}
}
void CreateBinTree(BinTreeNode<T> *&t, const T *&str)
{
if (*str == flag || *str == '\0')
{
t = NULL;
}
else
{
t = new BinTreeNode<T>(*str);
CreateBinTree(t->left, ++str);
CreateBinTree(t->right, ++str);
}
}
private:
T flag;
BinTreeNode<T>* root;
};
#endif // ! _BINARYTREE_h
测试
#include"BinaryTree.h"
#include<stdio.h>
int main()
{
const char *VLR = "ABCDEFGH";
const char *LVR = "CBEDFAGH";
const char *LRV = "CEFDBHGA";
BinaryTree<char> bt;
bt.CreateBinTree_VLR_LVR(VLR, LVR);
//BinTreeNode<char>*head = bt.ConvertList();
/*BinaryTree<char> bt1('#');
const char *str = "ABC##DE##F##G#H##";
bt1.CreateBinTree(str);
bool flag = bt.Equal(bt1);
cout << flag << endl;*/
BinaryTree<char> bt1('#');
const char *str = "BC##DE##F##";
bt1.CreateBinTree(str);
bool flag = bt.Equal_Is_Subtree(bt1);
cout << flag << endl;
}
/*int main()
{
BinaryTree<char> bt('#');
const char *str = "ABC##DE##F##G#H##";
bt.CreateBinTree(str);
//采用递归方法
bt.PreOrder(); cout << endl;//前序遍历
bt.InOrder(); cout << endl;//中序遍历
bt.PostOrder(); cout << endl;//后序遍历
//采用非递归方法
bt.Non_Recursive_PreOrder(); cout << endl;//前序遍历
bt.Non_Recursive_InOrder(); cout << endl;//中序遍历
bt.Non_Recursive_PostOrder(); cout << endl;//后序遍历
bt.SwapLeftRightChild();
bt.PostOrder(); cout << endl;
BinTreeNode<char>*pt = bt.CommonParent('E','G');
cout << "size:" << bt.size() << endl;
cout << "height:" << bt.height() << endl;
cout << "LeafSize:" << bt.LeafSize() << endl;
cout << "Weight:" << bt.Weight() << endl;
return 0;
}*/