二叉树知识点
2016-02-18 17:43
253 查看
高度为h的平衡二叉树
最少包含的节点个数为:
f(1) = 1,f(2)=2,f(3)=4,f(4)=7............f(n+2) = f(n+1)+f(n)+1.
最少包含的叶节点个数为:
f(1)=1,f(2)=1,f(3)=2,f(4)=3,f(5)=5,f(6)=8.......f(n+2)=f(n+1)+f(n).//斐波那契数列。
#include <iostream>
#include <queue>
#include <stack>
#include <list>
using namespace std;
class binaryTreeNode{
public:
int el;
binaryTreeNode * left;
binaryTreeNode * right;
binaryTreeNode(){
left = right = 0;
}
binaryTreeNode(const int e,binaryTreeNode*l=0,binaryTreeNode*r=0){
el=e;
left = l;
right = r;
}
};
class binaryTree{
public:
binaryTree(){
root = 0;
}
binaryTree(binaryTreeNode*r){
root = r;
}
bool isEmpty()const{
return root==0;
}
int GetNum(){//求二叉树的节点个数
return GetNum(root);
}
int deep(){//求二叉树的深度
return deep(root);
}
//递归深度优先遍历
void prorder(){
prorder(root);
}
void inorder(){
inorder(root);
}
void postorder(){
postorder(root);
}
//用队列实现广度优先遍历
void levelTravel(){
levelTravel(root);
}
//求二叉树第k层的节点个数
int getNumKLevel(int k){
getNumKLevel(root,k);
}
//求二叉树中叶节点的个数
int leafNum(){
return leafNum(root);
}
//判断两棵二叉树是否结构相同
bool strcmp(binaryTree&t){
return strcmp(root,t.root);
}
//判断二叉树是否为平衡二叉树
bool isAVL(){
return isAVL(root);
}
//求二叉树的镜像
binaryTree Mirror(){
return binaryTree(Mirror(root));
}
//求二叉树种两个节点的最低公共祖先
binaryTreeNode* getLastCommonParent(binaryTreeNode*p1,binaryTreeNode*p2){
return getLastCommonParent(root,p1,p2);
}
//非递归的深度优先遍历
void iterproder();
void iterinorder();
void iterpostorder();
//判断二叉树是否是完全二叉树
bool isComplate(){
return isComplate(root);
}
//判断是否是二叉排序树
bool isBinarySort(){
return isBinarySort(root);
}
protected:
binaryTreeNode * root;
int GetNum(binaryTreeNode*);//二叉树的节点个数
int deep(binaryTreeNode*);//二叉树的深度
virtual void visit(binaryTreeNode*p){
cout<<p->el<<" ";
}
//递归深度优先遍历
void prorder(binaryTreeNode*);
void inorder(binaryTreeNode*);
void postorder(binaryTreeNode*);
//广度优先遍历
void levelTravel(binaryTreeNode*);
//求二叉树第K层的节点个数
getNumKLevel(binaryTreeNode*,int);
//求二叉树中叶节点的个数
int leafNum(binaryTreeNode*);
//判断两棵二叉树是否相同
bool strcmp(binaryTreeNode*,binaryTreeNode*);
//判断二叉树是否为平衡二叉树
bool isAVL(binaryTreeNode*);
//求二叉树的镜像
binaryTreeNode* Mirror(binaryTreeNode*);
//求二叉树种两个节点的最低公共祖先
bool foundNode(binaryTreeNode*,binaryTreeNode*);
binaryTreeNode* getLastCommonParent(binaryTreeNode*,binaryTreeNode*,binaryTreeNode*);
bool getNodePath(binaryTreeNode*,binaryTreeNode*,list<binaryTreeNode*>&);
binaryTreeNode* getLastCommonParent2(binaryTreeNode*,binaryTreeNode*,binaryTreeNode*);
//判断是否是完全二叉树
bool isComplate(binaryTreeNode*);
//判断是否是二叉排序树
bool isBinarySort(binaryTreeNode*);
};
//二叉树的节点个数
int binaryTree::GetNum(binaryTreeNode*p){
if(p==0)
return 0;
else
return 1+GetNum(p->left)+GetNum(p->right);
}
//二叉树的深度
int binaryTree::deep(binaryTreeNode*p){
if(p==0)
return 0;
else
return 1+(deep(p->left)>deep(p->right))?deep(p->left):deep(p->right);
}
//3种递归深度优先遍历
void binaryTree::prorder(binaryTreeNode*p){
if(p!=0)
{
visit(p);
prorder(p->left);
prorder(p->right);
}
}
void binaryTree::inorder(binaryTreeNode*p){
if(p!=0){
inorder(p->left);
visit(p);
inorder(p->right);
}
}
void binaryTree::postorder(binaryTreeNode*p){
if(p!=0){
postorder(p->left);
postorder(p->right);
visit(p);
}
}
//用队列实现广度优先遍历
void binaryTree::levelTravel(binaryTreeNode*p){
queue<binaryTreeNode*> q;
binaryTreeNode * t;
if(p!=0)
{
q.push(p);
while(!q.empty()){
t = q.front();
visit(t);
q.pop();
if(t->left);
q.push(t->left);
if(t->right)
q.push(t->right);
}
}
}
//求二叉树第K层的节点个数
int binaryTree::getNumKLevel(binaryTreeNode*p,int k){
if(p==0||k<1)
return 0;
else if(k==1)
return 1;
return (getNumKLevel(p->left,k-1)+getNumKLevel(p->right,k-1));
}
//求二叉树中叶节点的个数
int binaryTree::leafNum(binaryTreeNode*p){
if(p==0)
return 0;
else if(p->left==0&&p->right==0)
return 1;
else
return (leafNum(p->right)+leafNum(p->left));
}
//判断两棵二叉树是否相同
bool binaryTree::strcmp(binaryTreeNode*p1,binaryTreeNode*p2){
if(p1==0&&p2==0)
return true;
else if(p1==0||p2==0)
return false;
else
return strcmp(p1->left,p2->left)&&(p1->ri
4000
ght,p2->right);
}
//判断是否为平衡二叉树
bool binaryTree::isAVL(binaryTreeNode*p){
if(p==0)
return true;
int left = deep(p->left);
int right = deep(p->right);
int diff = right - left;
if(diff <=-1 || diff >= 1)
return false;
return(isAVL(p->left)&&isAVL(p->right));
}
//求二叉树的镜像
binaryTreeNode* binaryTree::Mirror(binaryTreeNode*p){
binaryTreeNode * p1;
if(p==0)
return 0;
binaryTreeNode * pl = Mirror(p->left);
binaryTreeNode * pr = Mirror(p->right);
p1->left = pr;
p1->right = pl;
return p1;
}
//求二叉树种两个节点的最低公共祖先
bool binaryTree::foundNode(binaryTreeNode*p1,binaryTreeNode*p2){
if(p1==0||p2==0)
return false;
if(p1==p2)
return true;
bool found = foundNode(p1->left,p2);
if(!found)
found = foundNode(p1->right,p2);
return found;
}
//递归解法:
//如果两个节点分别在根节点的左子树和右子树,则返回根节点
//如果两个节点都在左子树,则递归处理左子树;如果两个节点都在右子树,则递归处理右子树
binaryTreeNode* binaryTree::getLastCommonParent(binaryTreeNode*r,binaryTreeNode*p1,binaryTreeNode*p2){
if(foundNode(r->left,p1)){
if(foundNode(r->right,p2))
return r;
else
return getLastCommonParent(r->left,p1,p2);
}
else{
if(foundNode(r->left,p2))
return r;
else
return getLastCommonParent(r->right,p1,p2);
}
}
//非递归解法:
//先求从根节点到两个节点的路径,然后再比较对应路径的节点就行,最后一个相同的节点也就是他们在二叉树中的最低公共祖先节点
bool binaryTree::getNodePath(binaryTreeNode*r,binaryTreeNode*p,list<binaryTreeNode*>&path){
if(r==p){
path.push_back(r);
return true;
}
if(r==0)
return false;
path.push_back(r);
bool found = false;
found = getNodePath(r->left,p,path);
if(!found)
found = getNodePath(r->right,p,path);
if(!found)
path.pop_back();
return found;
}
binaryTreeNode*binaryTree::getLastCommonParent2(binaryTreeNode*r,binaryTreeNode*p1,binaryTreeNode*p2){
if(r==0||p1==0||p2==0)
return nullptr;
list<binaryTreeNode*>path1;
bool bresult1 = getNodePath(r,p1,path1);
list<binaryTreeNode*>path2;
bool bresult2 = getNodePath(r,p2,path2);
if(!bresult1||!bresult2)
return nullptr;
binaryTreeNode * pLast = NULL;
list<binaryTreeNode*>::const_iterator iter1 = path1.begin();
list<binaryTreeNode*>::const_iterator iter2 = path2.begin();
while(iter1!=path1.end()&&iter2!=path2.end()){
if(*iter1 == *iter2)
pLast = *iter1;
iter1++;
iter2++;
}
return pLast;
}
//非递归先序遍历
void binaryTree::iterproder(){
stack<binaryTreeNode*> s;
binaryTreeNode*p = root;
if(p!=0){
s.push(p);
while(!s.empty()){
p = s.top();
s.pop();
visit(p);
if(p->right!=0)
s.push(p->right);
if(p->left!=0)
s.push(p->left);
}
}
}
//非递归中序遍历
//若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理
//若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子
void binaryTree::iterinorder(){
binaryTreeNode * p =root;
stack<binaryTreeNode*>s;
while(p!=0||!s.empty()){
while(p!=0){
s.push(p);
p=p->left;
}
if(!s.empty()){
p=s.top();
visit(p);
s.pop();
p=p->right;
}
}
}
//非递归后序遍历
/*对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,
但是此时不能将其出栈并访问,因此其右孩子还为被访问。所以接下来按照相同的规则对其右子树进行相同的处理,
当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。
这样就保证了正确的访问顺序。可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。
因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。
*/
void binaryTree::iterpostorder(){
stack<binaryTreeNode*>s;
binaryTreeNode*p = root,*q=root;
while(p!=0){
for(;p->left!=0;p=p->left)
s.push(p);
while(p->right==0||p->right==q){
visit(p);
q=p;
if(s.empty())
return;
p=s.top();
s.pop();
}
s.push(p);
p=p->right;
}
}
//判断是否是完全二叉树
bool binaryTree::isComplate(binaryTreeNode*p){
queue<binaryTreeNode*>q;
if(p==0)
return true;
int tag = 0;
q.push(p);
while(!q.empty()){
p = q.front();
q.pop();
if(p->left&&!tag)
q.push(p->left);
else if(p->left)
return false;
else
tag =1;
if(p->right&&!tag)
q.push(p->right);
else if(p->right)
return false;
else
tag =1;
}
return true;
}
//判断是否是二叉查找树
bool binaryTree::isBinarySort(binaryTreeNode*p){
binaryTreeNode* pre = 0;
stack<binaryTreeNode*> s;
while(p!=0||!s.empty()){
if(p){
s.push(p);
p=p->left;
}
else{
p = s.top();
s.pop();
if(pre&&(pre->el>=p->el))
return false;
pre = p;
p=p->right;
}
}
return true;
}
int main()
{
cout << "Hello world!" << endl;
return 0;
}
最少包含的节点个数为:
f(1) = 1,f(2)=2,f(3)=4,f(4)=7............f(n+2) = f(n+1)+f(n)+1.
最少包含的叶节点个数为:
f(1)=1,f(2)=1,f(3)=2,f(4)=3,f(5)=5,f(6)=8.......f(n+2)=f(n+1)+f(n).//斐波那契数列。
#include <iostream>
#include <queue>
#include <stack>
#include <list>
using namespace std;
class binaryTreeNode{
public:
int el;
binaryTreeNode * left;
binaryTreeNode * right;
binaryTreeNode(){
left = right = 0;
}
binaryTreeNode(const int e,binaryTreeNode*l=0,binaryTreeNode*r=0){
el=e;
left = l;
right = r;
}
};
class binaryTree{
public:
binaryTree(){
root = 0;
}
binaryTree(binaryTreeNode*r){
root = r;
}
bool isEmpty()const{
return root==0;
}
int GetNum(){//求二叉树的节点个数
return GetNum(root);
}
int deep(){//求二叉树的深度
return deep(root);
}
//递归深度优先遍历
void prorder(){
prorder(root);
}
void inorder(){
inorder(root);
}
void postorder(){
postorder(root);
}
//用队列实现广度优先遍历
void levelTravel(){
levelTravel(root);
}
//求二叉树第k层的节点个数
int getNumKLevel(int k){
getNumKLevel(root,k);
}
//求二叉树中叶节点的个数
int leafNum(){
return leafNum(root);
}
//判断两棵二叉树是否结构相同
bool strcmp(binaryTree&t){
return strcmp(root,t.root);
}
//判断二叉树是否为平衡二叉树
bool isAVL(){
return isAVL(root);
}
//求二叉树的镜像
binaryTree Mirror(){
return binaryTree(Mirror(root));
}
//求二叉树种两个节点的最低公共祖先
binaryTreeNode* getLastCommonParent(binaryTreeNode*p1,binaryTreeNode*p2){
return getLastCommonParent(root,p1,p2);
}
//非递归的深度优先遍历
void iterproder();
void iterinorder();
void iterpostorder();
//判断二叉树是否是完全二叉树
bool isComplate(){
return isComplate(root);
}
//判断是否是二叉排序树
bool isBinarySort(){
return isBinarySort(root);
}
protected:
binaryTreeNode * root;
int GetNum(binaryTreeNode*);//二叉树的节点个数
int deep(binaryTreeNode*);//二叉树的深度
virtual void visit(binaryTreeNode*p){
cout<<p->el<<" ";
}
//递归深度优先遍历
void prorder(binaryTreeNode*);
void inorder(binaryTreeNode*);
void postorder(binaryTreeNode*);
//广度优先遍历
void levelTravel(binaryTreeNode*);
//求二叉树第K层的节点个数
getNumKLevel(binaryTreeNode*,int);
//求二叉树中叶节点的个数
int leafNum(binaryTreeNode*);
//判断两棵二叉树是否相同
bool strcmp(binaryTreeNode*,binaryTreeNode*);
//判断二叉树是否为平衡二叉树
bool isAVL(binaryTreeNode*);
//求二叉树的镜像
binaryTreeNode* Mirror(binaryTreeNode*);
//求二叉树种两个节点的最低公共祖先
bool foundNode(binaryTreeNode*,binaryTreeNode*);
binaryTreeNode* getLastCommonParent(binaryTreeNode*,binaryTreeNode*,binaryTreeNode*);
bool getNodePath(binaryTreeNode*,binaryTreeNode*,list<binaryTreeNode*>&);
binaryTreeNode* getLastCommonParent2(binaryTreeNode*,binaryTreeNode*,binaryTreeNode*);
//判断是否是完全二叉树
bool isComplate(binaryTreeNode*);
//判断是否是二叉排序树
bool isBinarySort(binaryTreeNode*);
};
//二叉树的节点个数
int binaryTree::GetNum(binaryTreeNode*p){
if(p==0)
return 0;
else
return 1+GetNum(p->left)+GetNum(p->right);
}
//二叉树的深度
int binaryTree::deep(binaryTreeNode*p){
if(p==0)
return 0;
else
return 1+(deep(p->left)>deep(p->right))?deep(p->left):deep(p->right);
}
//3种递归深度优先遍历
void binaryTree::prorder(binaryTreeNode*p){
if(p!=0)
{
visit(p);
prorder(p->left);
prorder(p->right);
}
}
void binaryTree::inorder(binaryTreeNode*p){
if(p!=0){
inorder(p->left);
visit(p);
inorder(p->right);
}
}
void binaryTree::postorder(binaryTreeNode*p){
if(p!=0){
postorder(p->left);
postorder(p->right);
visit(p);
}
}
//用队列实现广度优先遍历
void binaryTree::levelTravel(binaryTreeNode*p){
queue<binaryTreeNode*> q;
binaryTreeNode * t;
if(p!=0)
{
q.push(p);
while(!q.empty()){
t = q.front();
visit(t);
q.pop();
if(t->left);
q.push(t->left);
if(t->right)
q.push(t->right);
}
}
}
//求二叉树第K层的节点个数
int binaryTree::getNumKLevel(binaryTreeNode*p,int k){
if(p==0||k<1)
return 0;
else if(k==1)
return 1;
return (getNumKLevel(p->left,k-1)+getNumKLevel(p->right,k-1));
}
//求二叉树中叶节点的个数
int binaryTree::leafNum(binaryTreeNode*p){
if(p==0)
return 0;
else if(p->left==0&&p->right==0)
return 1;
else
return (leafNum(p->right)+leafNum(p->left));
}
//判断两棵二叉树是否相同
bool binaryTree::strcmp(binaryTreeNode*p1,binaryTreeNode*p2){
if(p1==0&&p2==0)
return true;
else if(p1==0||p2==0)
return false;
else
return strcmp(p1->left,p2->left)&&(p1->ri
4000
ght,p2->right);
}
//判断是否为平衡二叉树
bool binaryTree::isAVL(binaryTreeNode*p){
if(p==0)
return true;
int left = deep(p->left);
int right = deep(p->right);
int diff = right - left;
if(diff <=-1 || diff >= 1)
return false;
return(isAVL(p->left)&&isAVL(p->right));
}
//求二叉树的镜像
binaryTreeNode* binaryTree::Mirror(binaryTreeNode*p){
binaryTreeNode * p1;
if(p==0)
return 0;
binaryTreeNode * pl = Mirror(p->left);
binaryTreeNode * pr = Mirror(p->right);
p1->left = pr;
p1->right = pl;
return p1;
}
//求二叉树种两个节点的最低公共祖先
bool binaryTree::foundNode(binaryTreeNode*p1,binaryTreeNode*p2){
if(p1==0||p2==0)
return false;
if(p1==p2)
return true;
bool found = foundNode(p1->left,p2);
if(!found)
found = foundNode(p1->right,p2);
return found;
}
//递归解法:
//如果两个节点分别在根节点的左子树和右子树,则返回根节点
//如果两个节点都在左子树,则递归处理左子树;如果两个节点都在右子树,则递归处理右子树
binaryTreeNode* binaryTree::getLastCommonParent(binaryTreeNode*r,binaryTreeNode*p1,binaryTreeNode*p2){
if(foundNode(r->left,p1)){
if(foundNode(r->right,p2))
return r;
else
return getLastCommonParent(r->left,p1,p2);
}
else{
if(foundNode(r->left,p2))
return r;
else
return getLastCommonParent(r->right,p1,p2);
}
}
//非递归解法:
//先求从根节点到两个节点的路径,然后再比较对应路径的节点就行,最后一个相同的节点也就是他们在二叉树中的最低公共祖先节点
bool binaryTree::getNodePath(binaryTreeNode*r,binaryTreeNode*p,list<binaryTreeNode*>&path){
if(r==p){
path.push_back(r);
return true;
}
if(r==0)
return false;
path.push_back(r);
bool found = false;
found = getNodePath(r->left,p,path);
if(!found)
found = getNodePath(r->right,p,path);
if(!found)
path.pop_back();
return found;
}
binaryTreeNode*binaryTree::getLastCommonParent2(binaryTreeNode*r,binaryTreeNode*p1,binaryTreeNode*p2){
if(r==0||p1==0||p2==0)
return nullptr;
list<binaryTreeNode*>path1;
bool bresult1 = getNodePath(r,p1,path1);
list<binaryTreeNode*>path2;
bool bresult2 = getNodePath(r,p2,path2);
if(!bresult1||!bresult2)
return nullptr;
binaryTreeNode * pLast = NULL;
list<binaryTreeNode*>::const_iterator iter1 = path1.begin();
list<binaryTreeNode*>::const_iterator iter2 = path2.begin();
while(iter1!=path1.end()&&iter2!=path2.end()){
if(*iter1 == *iter2)
pLast = *iter1;
iter1++;
iter2++;
}
return pLast;
}
//非递归先序遍历
void binaryTree::iterproder(){
stack<binaryTreeNode*> s;
binaryTreeNode*p = root;
if(p!=0){
s.push(p);
while(!s.empty()){
p = s.top();
s.pop();
visit(p);
if(p->right!=0)
s.push(p->right);
if(p->left!=0)
s.push(p->left);
}
}
}
//非递归中序遍历
//若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理
//若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子
void binaryTree::iterinorder(){
binaryTreeNode * p =root;
stack<binaryTreeNode*>s;
while(p!=0||!s.empty()){
while(p!=0){
s.push(p);
p=p->left;
}
if(!s.empty()){
p=s.top();
visit(p);
s.pop();
p=p->right;
}
}
}
//非递归后序遍历
/*对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,
但是此时不能将其出栈并访问,因此其右孩子还为被访问。所以接下来按照相同的规则对其右子树进行相同的处理,
当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。
这样就保证了正确的访问顺序。可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。
因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。
*/
void binaryTree::iterpostorder(){
stack<binaryTreeNode*>s;
binaryTreeNode*p = root,*q=root;
while(p!=0){
for(;p->left!=0;p=p->left)
s.push(p);
while(p->right==0||p->right==q){
visit(p);
q=p;
if(s.empty())
return;
p=s.top();
s.pop();
}
s.push(p);
p=p->right;
}
}
//判断是否是完全二叉树
bool binaryTree::isComplate(binaryTreeNode*p){
queue<binaryTreeNode*>q;
if(p==0)
return true;
int tag = 0;
q.push(p);
while(!q.empty()){
p = q.front();
q.pop();
if(p->left&&!tag)
q.push(p->left);
else if(p->left)
return false;
else
tag =1;
if(p->right&&!tag)
q.push(p->right);
else if(p->right)
return false;
else
tag =1;
}
return true;
}
//判断是否是二叉查找树
bool binaryTree::isBinarySort(binaryTreeNode*p){
binaryTreeNode* pre = 0;
stack<binaryTreeNode*> s;
while(p!=0||!s.empty()){
if(p){
s.push(p);
p=p->left;
}
else{
p = s.top();
s.pop();
if(pre&&(pre->el>=p->el))
return false;
pre = p;
p=p->right;
}
}
return true;
}
int main()
{
cout << "Hello world!" << endl;
return 0;
}
相关文章推荐