參考:https://blog.csdn.net/luckyxiaoqiang/article/details/7518888#topic9
#include <iostream>
#include <queue>
using namespace std;
//二叉樹節點
struct BTNode{
int value;
struct BTNode *pLeft;
struct BTNode *pRight;
};
class MyBT
{
public:
MyBT(){}
~MyBT(){}
bool isempty(BTNode *Root);
void creatBT(BTNode *Root);
int cntNode(BTNode *Root);
int GetDepth(BTNode *Root);
int GetLeafNodeNum(BTNode *Root);
int GetNodeNumKthLevel(BTNode *Root,int k);
void PreOrder(BTNode *Root);
void InOrder(BTNode *Root);
void PostOrder(BTNode *Root);
void LevelTraverse(BTNode *Root);
bool IsCompleteBinaryTree(BTNode *Root);
};
bool MyBT::isempty(BTNode *Root){
if(Root->pLeft==NULL&&Root->pRight==NULL)
return true;
return false;
}
void MyBT::creatBT(BTNode *Root){
//左節點
BTNode *PL = Root;
BTNode *tmp = new BTNode;
tmp->value = 1;
tmp->pLeft = NULL;
tmp->pRight = NULL;
PL->pLeft = tmp;
PL = tmp;
BTNode *tmp5 = new BTNode;
tmp5->value = 5;
tmp5->pLeft = NULL;
tmp5->pRight = NULL;
PL->pLeft = tmp5;
BTNode *tmp6 = new BTNode;
tmp6->value = 6;
tmp6->pLeft = NULL;
tmp6->pRight = NULL;
PL->pRight = tmp6;
//右節點
BTNode *PR = Root;
BTNode *tmp1 = new BTNode;
tmp1->value = 2;
tmp1->pLeft = NULL;
tmp1->pRight = NULL;
PR->pRight = tmp1;
PR = tmp1;
BTNode *tmp2 = new BTNode;
tmp2->value = 3;
tmp2->pLeft = NULL;
tmp2->pRight = NULL;
PR->pLeft = tmp2;
// BTNode *tmp3 = new BTNode;
// tmp3->value = 4;
// tmp3->pLeft = NULL;
// tmp3->pRight = NULL;
// PR->pRight = tmp3;
}
/*****************求二叉樹中的節點個數(遞歸)********************
(1)如果二叉樹爲空,節點個數爲0
(2)如果二叉樹不爲空,二叉樹節點個數 = 左子樹節點個數 + 右子樹節點個數 + 1
*/
int MyBT::cntNode(BTNode *Root){
if(Root==NULL) //遞歸出口
return 0;
//return cntNode(Root->pLeft)+cntNode(Root->pRight)+1;
int depthLeft = cntNode(Root->pLeft);
int depthRight = cntNode(Root->pRight);
return (depthLeft + depthRight + 1);
}
/*****************求二叉樹的深度(遞歸)********************
(1)如果二叉樹爲空,二叉樹的深度爲0
(2)如果二叉樹不爲空,二叉樹的深度 = max(左子樹深度, 右子樹深度) + 1
*/
int MyBT::GetDepth(BTNode *Root){
if(Root==NULL) //遞歸出口
return 0;
int depthLeft = GetDepth(Root->pLeft);
int depthRight = GetDepth(Root->pRight);
return depthLeft > depthRight ? (depthLeft + 1) : (depthRight + 1);
}
/*****************求二叉樹的葉子節點數目(遞歸)********************
說明:節點數目 = 內部節點數目+葉子節點數目;
沒有左右子節點稱爲葉子節點;
算法:
(1)如果二叉樹爲空,返回0
(2)如果二叉樹不爲空且左右子樹爲空,返回1
(3)如果二叉樹不爲空,且左右子樹不同時爲空,返回左子樹中葉子節點個數加上右子樹中葉子節點個數
*/
int MyBT::GetLeafNodeNum(BTNode *Root){
if(Root==NULL)
return 0;
if(Root->pLeft==NULL && Root->pRight==NULL)
return 1;
int depthLeft = GetLeafNodeNum(Root->pLeft);
int depthRight = GetLeafNodeNum(Root->pRight);
return (depthLeft + depthRight);
}
/*****************求二叉樹k層數目(遞歸)********************
(1)如果二叉樹爲空或者k<0返回0
(2)如果二叉樹不爲空並且k==0(根節點爲第0層),返回1
(3)如果二叉樹不爲空且k>0,返回左子樹中k-1層的節點個數與右子樹k-1層節點個數之和
*/
int MyBT::GetNodeNumKthLevel(BTNode *Root,int k){
if(Root==NULL||k<0)
return 0;
if(k==0)
return 1;
int depthLeft = GetNodeNumKthLevel(Root->pLeft,k-1);
int depthRight = GetNodeNumKthLevel(Root->pRight,k-1);
return (depthLeft + depthRight);
}
/*****************求二叉樹前序遍歷(遞歸)********************
(1)如果二叉樹爲空,空操作
(2)如果二叉樹不爲空,訪問根節點,前序遍歷左子樹,前序遍歷右子樹
*/
void MyBT::PreOrder(BTNode *Root){
if(Root==NULL)
return;
cout<<Root->value<<" ";
PreOrder(Root->pLeft);
PreOrder(Root->pRight);
}
/*****************求二叉樹中序遍歷(遞歸)********************
(1)如果二叉樹爲空,空操作。
(2)如果二叉樹不爲空,中序遍歷左子樹,訪問根節點,中序遍歷右子樹
*/
void MyBT::InOrder(BTNode *Root){
if(Root==NULL)
return;
InOrder(Root->pLeft);
cout<<Root->value<<" ";
InOrder(Root->pRight);
}
/*****************求二叉樹後序遍歷(遞歸)********************
(1)如果二叉樹爲空,空操作
(2)如果二叉樹不爲空,後序遍歷左子樹,後序遍歷右子樹,訪問根節點
*/
void MyBT::PostOrder(BTNode *Root){
if(Root==NULL)
return;
PostOrder(Root->pLeft);
PostOrder(Root->pRight);
cout<<Root->value<<" ";
}
/*****************求二叉樹分層遍歷********************
相當於廣度優先搜索,使用隊列實現。隊列初始化,將根節點壓入隊列。當隊列不爲空,進行如下操作:
彈出一個節點,訪問,若左子節點或右子節點不爲空,將其壓入隊列。
*/
void MyBT::LevelTraverse(BTNode *Root){
if(Root==NULL)
return;
queue<BTNode*>q;
q.push(Root);
while (!q.empty()) {
BTNode *pNode = q.front();
q.pop();
cout<<pNode->value<<" ";
if(pNode->pLeft!=NULL)
q.push(pNode->pLeft);
if(pNode->pRight!=NULL)
q.push(pNode->pRight);
}
return;
}
/*****************判斷是否時完全二叉樹********************
按層次(從上到下,從左到右)遍歷二叉樹,當遇到一個節點的左子樹爲空時,則該節點右子樹必須爲空,
且後面遍歷的節點左右子樹都必須爲空,否則不是完全二叉樹。
*/
bool MyBT::IsCompleteBinaryTree(BTNode *Root){
if(Root==NULL)
return false;
bool havenochild = false;
bool result = true;
queue<BTNode*>q;
q.push(Root);
while (!q.empty()) {
BTNode *pNode = q.front();
q.pop();
if(havenochild){
if(pNode->pLeft!=NULL||pNode->pRight!=NULL){
return false;
break;
}
}
else{
if(pNode->pLeft!=NULL&&pNode->pRight!=NULL){
q.push(pNode->pLeft);
q.push(pNode->pRight);
}
else if(pNode->pLeft!=NULL&&pNode->pRight==NULL){
havenochild = true;
q.push(pNode->pLeft);
}
else if(pNode->pLeft==NULL&&pNode->pRight!=NULL){
return false;
break;
}
else
havenochild = true;
}
}
return result;
}
int main ()
{
MyBT *mybt = new MyBT();
BTNode *Root = new BTNode;
mybt->creatBT(Root);
cout<<"是否爲空 : "<<mybt->isempty(Root)<<endl;
cout<<"節點個數 : "<<mybt->cntNode(Root)<<endl;
cout<<"節點深度 : "<<mybt->GetDepth(Root)<<endl;
cout<<"葉子節點數目 : "<<mybt->GetLeafNodeNum(Root)<<endl;
cout<<"第k層的節點數 : "<<mybt->GetNodeNumKthLevel(Root,2)<<endl;
cout<<"是否時完全二叉樹 : "<<mybt->IsCompleteBinaryTree(Root)<<endl;
cout<<"前序遍歷 : ";
mybt->PreOrder(Root);
cout<<endl;
cout<<"中序遍歷 : ";
mybt->InOrder(Root);
cout<<endl;
cout<<"後序遍歷 : ";
mybt->PostOrder(Root);
cout<<endl;
cout<<"分層遍歷 : ";
mybt->LevelTraverse(Root);
cout<<endl;
delete mybt;
mybt = NULL;
delete Root;
Root =NULL;
return 0;
}