二叉樹基本功能實現
阿新 • • 發佈:2018-12-22
一、二叉樹的鏈式儲存
用連結串列來表示一顆二叉樹,每個結點由三個域組成,除了資料域,還有兩個指標域,分別用來存放左右孩子的儲存地址。
typedef struct BiTNode
{ char data;
struct BiTNode *lchild, *rchild;
} BiTNode,*BiTree;
二、二叉樹的遍歷
(一)先序遍歷(遞迴呼叫)
int PreOrderTraverse(BiTree T){ if(T==NULL) return OK; //空二叉樹 else{ cout<<T->data; //訪問根結點 PreOrderTraverse(T->lchild); //遞迴遍歷左子樹 PreOrderTraverse(T->rchild); //遞迴遍歷右子樹 } }
(二)中序遍歷(非遞迴實現)
非遞迴中序遍歷演算法思想
(1)首先二叉樹結點指標進棧,然後結點指標指向進棧結點的左子樹的跟結點。重複操作(1)直到指標指向空
(2)當棧非空時,從棧中退出一個節點的指標,訪問該節點,轉為(3)棧為空時,結束演算法。
(3)然後將指標指向訪問過的節點的右子樹的跟
#define MAXNODE 100 //二叉樹最大節點數 //定義二叉樹鏈式結構 typedef struct BitNode { char data; //資料域 struct BitNode *lchild,*rchild;//左右指標域 }BitNode,*BiTree; //二叉樹進行中序非遞迴遍歷 void NRInorder(BiTree t) { BiTree s; //s-指向當前節點 BiTree stack[MAXNODE]; //定義棧 int top=-1; //初始化棧頂指標 if(t==NULL) return; stack[++top]=t;//根指標入棧 s=t->lchild; //s指向左子樹 while(s!=NULL||top!=-1)//當存在節點(涉及到根下右子樹)或者棧不為空,進行遍歷 { while(s!=NULL) //如果存在節點,尋找最左子樹併入棧 { if(top>=MAXNODE-1) { printf("棧為滿\n"); return; } stack[++top]=s;//當前節點入棧 s=s->lchild; //左子樹進行遍歷 } if(top==-1) { printf("棧為空\n"); return; } s=stack[top--]; //彈出棧頂元素到s中 printf("%c ",s->data); //輸出當前節點元素值 s=s->rchild; //遍歷右子樹 } }
(三)後序遍歷
int PostOrderTraverse(BiTtree T)
{
if(T==NULL)
return OK;
else{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data<<" ";
}
}
三、求深度
int Getdepth(BiTtree T) { int l,r; if(!T) { return 0; } l=Getdepth(T->lchild); r=Getdepth(T->rchild); if(l>r) { return l+1; } else return r+1; }
四、求葉子結點個數
void CountLeaf(BiTtree root,int &count)//採用先序遍歷的遞迴演算法
{
if ( root!=NULL ) //非空二叉樹條件
{
if (!root->lchild && !root->rchild)//是葉子結點則統計並列印
{
count++;
//cout<<root->data<<endl;
}
if(root->lchild)
CountLeaf(root->lchild,count); //遞迴遍歷左子樹;
if(root->rchild)
CountLeaf(root->rchild,count); //遞迴遍歷右子樹;
}
}
綜合程式碼實現如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#define OK 1
using namespace std;
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTtree;
int count;
//按先序次序輸入二叉樹中結點的值,建立二叉樹T
void CreatBiTree(BiTtree &T)
{
char ch;
cin>>ch;
if(ch=='#')
T=NULL;
else
{
T=new BiTNode;
T->data=ch;
cout<<"請輸入"<<ch<<"的左孩子:";
CreatBiTree(T->lchild);
cout<<"請輸入"<<ch<<"的右孩子:";
CreatBiTree(T->rchild);
}
}
//先序遍歷
int PreOrderTraverse(BiTtree T)
{
if(T==NULL)
return OK; //空二叉樹
else
{
cout<<T->data<<" "; //訪問跟結點
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
//中序遍歷
/*
int InOrderTraverse(BiTtree T)
{
if(T==NULL)
return OK;
else
{
InOrderTraverse(T->lchild);
cout<<T->data<<" ";
InOrderTraverse(T->rchild);
}
} */
void InOrderTraverse(BiTtree T)
{
if(T!=NULL)
{
BiTNode *stack[100];
int top=-1;
BiTNode *t;
t=T;
while(top!=-1||t!=NULL)
{
while(t!=NULL)
{
stack[++top]=t;
t=t->lchild;
}
if(top!=-1)
{
t=stack[top--];
cout<<t->data<<" ";
t=t->rchild;
}
}
}
}
//後序遍歷
int PostOrderTraverse(BiTtree T)
{
if(T==NULL)
return OK;
else{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data<<" ";
}
}
void level(BiTtree T)
{
int front,rear;
front=rear=0;
BiTtree que[100];
BiTtree p;
if(T)
{
rear=(rear+1)%100;
que[rear]=T;
while(front!=rear)
{
front=(front+1)%100;
p=que[front];
cout<<p->data;
if(p->lchild)
{
rear=(rear+1)%100;
que[rear]=p->lchild;
}
if(p->rchild)
{
rear=(rear+1)%100;
que[rear]=p->rchild;
}
}
}
}
int getdepth(BiTtree T)
{
int l,r;
if(!T)
{
return 0;
}
l=getdepth(T->lchild);
r=getdepth(T->rchild);
if(l>r)
{
return l+1;
}
else
return r+1;
}
void CountLeaf(BiTtree root,int &count)//採用先序遍歷的遞迴演算法
{
if ( root!=NULL ) //非空二叉樹條件
{
if (!root->lchild && !root->rchild)//是葉子結點則統計並列印
{
count++;
//cout<<root->data<<endl;
}
if(root->lchild)
CountLeaf(root->lchild,count); //遞迴遍歷左子樹;
if(root->rchild)
CountLeaf(root->rchild,count); //遞迴遍歷右子樹;
}
}
void show_help()
{
cout<<"|------------------------------------------"<<endl;
cout<<"| 0.建立二叉樹 "<<endl;
cout<<"| 1.先序遍歷二叉樹 "<<endl;
cout<<"| 2.中序遍歷二叉樹 "<<endl;
cout<<"| 3.後序遍歷二叉樹 "<<endl;
cout<<"| 4.二叉樹的層序遍歷 "<<endl;
cout<<"| 5.二叉樹的深度 "<<endl;
cout<<"| 6.二叉樹的葉子結點數 "<<endl;
cout<<"|------------------------------------------"<<endl;
}
int main()
{
BiTtree root;
int operate_code;
show_help();
cout<<"請建立二叉樹並輸入二叉樹的根結點"<<endl;
CreatBiTree(root);
while(1)
{
cout<<"請選擇功能 "<<endl;
cin>>operate_code;
count=0;
if(operate_code==1)
{
if(root)
{
cout<<"先序輸出的結果為:";
PreOrderTraverse(root);
cout<<endl;
}
else
cout<<"該二叉樹為空"<<endl;
}
else if(operate_code==2)
{
if(root)
{
cout<<"中序輸出的結果為:";
InOrderTraverse(root);
cout<<endl;
}
else
cout<<"該二叉樹為空"<<endl;
}
else if(operate_code==3)
{
if(root)
{
cout<<"後序輸出的結果為:";
PostOrderTraverse(root);
cout<<endl;
}
else
cout<<"該二叉樹為空"<<endl;
}
else if(operate_code==4)
{
cout<<"二叉樹的層序遍歷是";
level(root);
cout<<endl;
}
else if(operate_code==5)
{
cout<<"二叉樹的深度是"<<getdepth(root)<<endl;
}
else if(operate_code==6)
{
CountLeaf(root,count);
cout<<"二叉樹的葉子節點個數為"<<count<<endl;
}
}
}