數據結構中樹這一塊兒一直是個難點和考點,剛好前幾天在面實習生,面試過程中問到了二叉樹並讓寫出代碼,就想自己再寫一遍二叉樹的常見操作,目的爲了留着以後用起來方便,於是乎,拿起書本又看了一遍,寫下這些代碼,編譯環境是VS2012。
更多關於數據結構學習教程請進碼神營地官網:www.icodegod.com
在Btree.h中的有下列聲明和定義:
typedef struct BtNode//二叉樹的數據結構
{
char data;
struct BtNode*lchild,*rchild;
}BtNode,*BTree;
void CreateBTree(BTree& Bt);//二叉樹的創建
void PreOrder(BTree &Bt);//二叉樹前序遍歷
void PreOrderNon(BTree &Bt);//二叉樹前序非遞歸遍歷
void MidOrder(BTree &Bt);//二叉樹中序遍歷
void MidOrderNon(BTree &Bt);//二叉樹非遞歸中序遍歷
void LastOrder(BTree &Bt);//二叉樹後序遍歷
void LastOrderNon(BTree &Bt);//二叉樹非遞歸後序遍歷
void LevelOrder(BTree &Bt);//二叉樹層次遍歷
BtNode * CommonParent1(BtNode *root,BtNode *bt1,BtNode *bt2);//求最近公共父節點
int Depth(BTree &Bt);//二叉樹的深度
int leafCount(BTree &Bt);//二叉樹葉子節點的個數
void Exchagechild(BTree &Bt);//交換二叉樹的左右孩子
bool IsBalanceTree(BTree &Bt);//是否爲平衡二叉樹
void DestroyTree(BtNode *Bt);//二叉樹的銷燬
在BTree.cpp中有一下函數實現:
#include<iostream>
#include"Btree.h"
#include<stack>
#include<queue>
using namespace std;
//先序創建二叉樹
void CreateBTree(BTree &Bt)
{
char ch;
cin>>ch;
if(ch == '#') Bt=NULL;
else
{
Bt = new BtNode;
Bt->data = ch;
CreateBTree(Bt->lchild);//遞歸創建左子樹
CreateBTree(Bt->rchild);//遞歸創建右子樹
}
}
//遞歸先序遍歷
void PreOrder(BTree &Bt)
{
if(Bt == NULL) return ;
cout<<Bt->data<<" ";
PreOrder(Bt->lchild);
PreOrder(Bt->rchild);
}
//非遞歸先序遍歷
void PreOrderNon(BTree &Bt)
{
if (Bt == NULL) return ;
stack<BTree> s;
BTree p = Bt;
while(!s.empty() || p != NULL)
{
if( p != NULL)
{
cout<<p->data<<" ";
s.push(p);
p = p->lchild;
}
if(!s.empty())
{
p = s.top();
s.pop();
p = p->rchild;
}
}
}
//遞歸中序遍歷
void MidOrder(BTree &Bt)
{
if (Bt == NULL) return ;
MidOrder(Bt->lchild);
cout<<Bt->data<<" ";
MidOrder(Bt->rchild);
}
//非遞歸中序遍歷
void MidOrderNon(BTree &Bt)
{
if(Bt == NULL) return ;
BTree p = Bt;
stack<BTree> s;
while( p != NULL || !s.empty() )
{
while( p != NULL)
{
s.push(p);
p = p->lchild;
}
if(!s.empty())
{
p = s.top();
s.pop();
cout<<p->data<<" ";
p = p->rchild;
}
}
}
//遞歸後序遍歷
void LastOrder(BTree &Bt)
{
if(Bt== NULL) return ;
LastOrder(Bt->lchild);
LastOrder(Bt->rchild);
cout<<Bt->data<<" ";
}
//非遞歸後序遍歷
void LastOrderNon(BTree &Bt)
{
if(Bt == NULL) return ;
stack<BTree> s;
BTree p = Bt;
BTree visted = NULL;
while(p != NULL || !s.empty())
{
while(p != NULL)
{
s.push(p);
p = p->lchild;
}
p = s.top();
if(p->rchild == NULL || p->rchild == visted)
{
cout<<p->data<<" ";
visted = p;
s.pop();
p = NULL;
}
else
{
p = p->rchild;
}
}
}
//層次遍歷
void LevelOrder(BTree &Bt)
{
queue<BTree> q;
BTree temp = NULL;
if(Bt != NULL) q.push(Bt);
while(!q.empty())
{
temp = q.front();
q.pop();
cout<<temp->data<< " ";
if(temp->lchild != NULL)
{
q.push(temp->lchild);
}
if(temp->rchild != NULL)
{
q.push(temp->rchild);
}
}
}
//求公共父節點,已知兩個子節點
BtNode * CommonParent(BtNode *root,BtNode *bt1,BtNode *bt2)
{
if(root == NULL)
return NULL;
if(bt1 == root || bt2 == root)
return root;
BtNode *left = CommonParent(root->lchild,bt1,bt2);
BtNode*right = CommonParent(root->rchild,bt1,bt2);
if(left && right )
return root;
return left ?left:right;
}
//二叉樹深度
int Depth(BTree &Bt)
{
if(Bt == NULL ) return 0;
int len1 = Depth(Bt->lchild);
int len2 = Depth(Bt->rchild);
return len1>len2?len1+1:len2+1;
}
//葉子節點總數
int leafCount(BTree &Bt)
{
if(Bt == NULL) return 0;
if(Bt->lchild== NULL && Bt->rchild == NULL)
{
return 1;
}
return leafCount(Bt->lchild)+leafCount(Bt->rchild);
}
//交換左右孩子
void Exchagechild(BTree &Bt)
{
if(Bt == NULL) return ;
BTree temp = NULL;
if(Bt->lchild || Bt->rchild)
{
temp = Bt->lchild;
Bt->lchild = Bt->rchild;
Bt->rchild = temp;
Exchagechild(Bt->lchild);
Exchagechild(Bt->rchild);
}
}
//是否是平衡二叉樹
bool IsBalanceTree(BTree &Bt)
{
if(Bt == NULL)
return true;
int ldepth = Depth(Bt->lchild);
int rdepth = Depth(Bt->rchild);
int dis = ldepth-rdepth;
if(dis >1 || dis <-1)
return false;
return IsBalanceTree(Bt->lchild) && IsBalanceTree(Bt->rchild);
}
//銷燬樹
void DestroyTree(BtNode *Bt)
{
if(Bt == NULL)
return ;
DestroyTree(Bt->lchild);
DestroyTree(Bt->rchild);
delete Bt;
}
int main()
{
BTree T;
CreateBTree(T);
cout<<"PreOrder:";
PreOrder(T);
cout<<endl;
cout<<"MidOrder:";
MidOrder(T);
cout<<endl;
cout<<"LastOrder:";
LastOrder(T);
cout<<endl;
cout<<"PreOrderNon:";
PreOrderNon(T);
cout<<endl;
cout<<"LevelOrder:";
LevelOrder(T);
cout<<endl;
cout<<"leafCount:";
cout<<leafCount(T)<<endl;
cout<<"Depth:";
cout<<Depth(T)<<endl;
cout<<"Exchangechild:";
Exchagechild(T);
PreOrder(T);
cout<<endl;
cout<<"MidOrderNon:";
MidOrderNon(T);
cout<<endl;
cout<<"LastOrderNon:";
LastOrderNon(T);
cout<<endl;
cout<<"IsBalanceTree:";
if(IsBalanceTree(T))
cout<<"IsBanlanceTree"<<endl;
else
cout<<"IsNotBanlanceTree"<<endl;
cout<<"CommonParent:";
cout<<(CommonParent(T,T->lchild->lchild,T->rchild->rchild))->data;
cout<<endl;
return 0;
}