#include "stdafx.h"
#include<string>
#include<iostream>
#define ERROR 0
#define OK 1
#define queuesize 20
using namespace std;
typedef struct BiTNode{
int data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
typedef struct Queue{
int front ,rear ;
BiTree data[queuesize];
int count;
}Queue;
/*======================================*\
|建立二叉樹
|@date 2012/11/27
\*======================================*/
//先序建立二叉樹
int create_BiTree(BiTree &T)
{
int ch;
cout<<"請輸入一個根結點的值(如果爲空,則輸入0)\n";
cin>>ch;
if (ch==0) T= NULL;
else
{
T=new BiTNode;
if (T== NULL) return ERROR;
T->data = ch;
create_BiTree(T->lchild); // 構造左子樹
create_BiTree(T->rchild); // 構造右子樹
}
return OK;
}
/*=========================================*\
|三種遍歷
|@author LiMing
|@date 2012/11/27
\*=========================================*/
int pre_order_traverse(BiTree T) //先序遍歷
{
if(T!=NULL)
{
cout<<T->data<<" ";
pre_order_traverse(T->lchild);
pre_order_traverse(T->rchild);
}
return OK;
}
int in_order_traverse(BiTree T)//中序遍歷
{
if(T!=NULL)
{
in_order_traverse(T->lchild);
cout<<T->data<<" ";
in_order_traverse(T->rchild);
}
return OK;
}
int past_order_traverse(BiTree T)//後序遍歷
{
if(T!=NULL)
{
past_order_traverse(T->lchild);
past_order_traverse(T->rchild);
cout<<T->data<<"";
}
return OK;
}
/*===================================*\
|非遞歸遍歷
\*===================================*/
int pre_order_traverse2(BiTree T)
{
BiTree p,s[20];
int top=0;
p=T;
while((p!=NULL)||(top>0))
{
while(p!=NULL)
{
cout<<p->data<<" ";
s[++top]=p;
p=p->lchild;
}
p=s[top--];
p=p->rchild;
}
return OK;
}
int pre_order_traverse3(BiTree T)
{
BiTree p,stack[20];
p=T;
int top=-1;
for(;;)
{
for(;p;p=p->lchild)
{
cout<<p->data<<"";
stack[++top]=p;
}
if(top==-1)break;
p=stack[top--];
p=p->rchild;
}
return OK;
}
int in_order_traverse2(BiTree T)
{
BiTree p, stack[20];
p=T;
int top=-1;
for(;;)
{
for(;p;p=p->lchild)
stack[++top]=p;
if(top==-1)break;
p=stack[top--];
cout<<p->data<<" ";
p=p->rchild;
}
return OK;
}
//非遞歸後序遍歷
int PastOrderTraverse2(BiTree T)
{
//此處省略一萬字啊啊啊,一般不用
return 0;
}
/*======================================*\
|層次遍歷法1
|@author LiMing
|@date 2012/11/28
\*======================================*/
int level_order_traverse1(BiTree T)
{ Queue *q;
BiTree p;
int flag=0; //定義flag爲層號
q=new Queue; //申請循環隊列空間
q->rear=q->front=q->count=0; //將循環隊列初始化爲空
q->data[q->rear]=T;
q->count++;
q->rear=(q->rear+1)%queuesize; //將根結點入隊
while (q->count) //若隊列不爲空,做以下操作
if(q->data[q->front]){ //當隊首元素不爲空指針,做以下操作
p=q->data[q->front]; //取隊首元素*p
cout<<p->data<<endl; //打印*p結點的數據域信息
++flag;
q->front=(q->front+1)%queuesize;
q->count--; //隊首元素出隊
if (q->count==queuesize) //若隊列爲隊滿,則打印隊滿信息,退出程序的執行
cout<<"the queue full!\n";
else{ //若隊列不滿,將*p結點的左孩子指針入隊
q->count++;q->data[q->rear]=p->lchild;
q->rear=(q->rear+1)%queuesize;
} //enf of if
if (q->count==queuesize) //若隊列爲隊滿,則打印隊滿信息,退出程序的執行
cout<<"the queue full!\n";
else{ //若隊列不滿,將*p結點的右孩子指針入隊
q->count++;q->data[q->rear]=p->rchild;
q->rear=(q->rear+1)%queuesize;
} //end of if
} //end of if
else{ //當隊首元素爲空指針,將空指針出隊
q->front=(q->front+1)%queuesize;
q->count--;
}
cout<<endl;
return OK;
} //end of LevelOrder
/*======================================*\
|層次遍歷法2
|@author LiMing
|@date 2012/11/29
\*======================================*/
int level_order_traverse2(BiTree T)
{
Queue *temp;
BiTree p;
temp=new Queue;
p=T;
if(!temp) return 0;
else
{
temp->count=0;
temp->front=-1;
temp->rear =-1;
}
temp->data[++temp->rear]=p;
temp->count++;
for(;temp->count;)
{
cout<<temp->data[++temp->front]->data<<" ";
temp->count--;
if(temp->data[temp->front]->lchild)
{
temp->data[++temp->rear]=temp->data[temp->front]->lchild;
temp->count++;
}
if(temp->data[temp->front]->rchild)
{
temp->data[++temp->rear]=temp->data[temp->front]->rchild;
temp->count++;
}
}
return 1;
}
/*===========================================*\
|與二叉樹的性質有關的幾種算法
|@author LiMinng
|@date 2012/11/28
\*===========================================*/
/**
*遞歸是不好實現的
*採用輔助棧的形式
*利用先序遍歷的思想
*/
int get_all_node(BiTree T)
{
BiTree p,s[20];
int num_node=0;
int top=0;
p=T;
while((p!=NULL)||(top>0))
{
while(p!=NULL)
{
num_node++;
s[++top]=p;
p=p->lchild;
}
p=s[top--];
p=p->rchild;
}
return num_node;
}
/**
*循環體部分化爲for()循環後
for(;;)
{
for(;p;p=p->lchild)
{
num_node++;
s[++top]=p;
}
if(top==0) break;
p=s[top--];
p=p->rchild;
}
*/
/**
*利用遞歸算法得到度爲0的結點的個數
*不容易理解 效率也不高
*/
int get_node0_1(BiTree T)//
{
int num1,num2;
if(T==NULL)
return 0;
else
{
if((T->lchild==NULL)&&(T->rchild==NULL))
return 1;
else
{
num1=get_node0_1(T->lchild);
num2=get_node0_1(T->rchild);
return (num1+num2);
}
}
}
/**
*利用非遞歸算法得到度爲0的結點的個數
*容易理解 效率高
*/
int get_node0_2(BiTree T)
{
int num=0;
BiTree p=T,s[20];
int top=0;
while((p!=NULL)||(top>0))
{
while(p!=NULL)
{
s[++top]=p;
p=p->lchild;
}
p=s[--top];
if(p->rchild==NULL)
{
++num;
}
else
p=p->rchild;
}
return num;
}
int get_node1(BiTree T) //利用總的關係求出度爲1的結點的個數
{
int num=get_all_node(T)-2*get_node0_1(T)+1;
return num;
}
int get_node1_1(BiTree T) //非遞歸算法,同時利用關係求度爲1的結點。
{
int num=get_all_node(T)-2*get_node0_2(T)+1;
return num;
}
int get_node2(BiTree T) //利用度爲2的結點個數與度爲0的結點個數的關係得到
{
int num=get_node0_1(T)-1;
return num;
}
int get_node2_1(BiTree T) //非遞歸算法,同時利用關係求度爲2的結點。
{
int num=get_node0_2(T)-1;
return num;
}
int get_node(BiTree T)
{
int get;
cout<<"請輸入你要查找的結點的度\n"<<endl;
cout<<"1.查詢度爲0的所有結點的個數\n"<<endl;
cout<<"2.查詢度爲1的所有結點的個數\n"<<endl;
cout<<"3.查詢度爲2的所有結點的個數\n"<<endl;
cin>>get;
switch(get){
case 1:
cout<<"度爲0的所有結點的個數是%d\n"<<get_node0_1(T)<<endl;
break;
case 2:
cout<<"度爲1的所有結點的個數是%d\n"<<get_node1(T)<<endl;
break;
case 3:
cout<<"度爲2的所有結點的個數是%d\n"<<get_node2(T)<<endl;
break;
}
return OK;
}
int get_node_1(BiTree T) //利用非遞歸算法的實現
{
int get;
cout<<"下面是用非遞歸算法來查詢\n"<<endl;
cout<<"請輸入你要查找的結點的度\n"<<endl;
cout<<"1.查詢度爲0的所有結點的個數\n"<<endl;
cout<<"2.查詢度爲1的所有結點的個數\n"<<endl;
cout<<"3.查詢度爲2的所有結點的個數\n"<<endl;
cin>>get;
switch(get){
case 1:
cout<<"度爲0的所有結點的個數是%d\n"<<get_node0_2(T)<<endl;
break;
case 2:
cout<<"度爲1的所有結點的個數是%d\n"<<get_node1_1(T)<<endl;
break;
case 3:
cout<<"度爲2的所有結點的個數是%d\n"<<get_node2_1(T)<<endl;
break;
}
return OK;
}
/**
*求樹的深度
*/
int height(BiTree T)
{
BiTree p=T;
int a,b;
if(p==NULL)
return 0;
else{
if((p->lchild==NULL)&&(p->rchild==NULL))
return 1;
else{
a=height(p->rchild);
b=height(p->lchild);
if(a>b)
return (a+1);
else
return (b+1);
}
}
}
/**
*採用遞歸算法來實現判斷是否爲完全二叉樹
*/
int judge(BiTree T)
{
if(T ==NULL)
return 0;
if(T->lchild == NULL && T->rchild== NULL)
return 1;
if(T->lchild == NULL && T->rchild != NULL||T->lchild!=NULL &&T->rchild==NULL)
return 0;
return judge(T->lchild) & judge(T->rchild);
}
int exchange(BiTree T)
{
BiTree p=T;
int exch;
if(p==NULL)
return OK;
else
{
if(p->lchild!=NULL && p->rchild!=NULL)
{
exch=p->lchild->data;
p->lchild->data=p->rchild->data;
p->rchild->data=exch;
exchange(p->lchild);
exchange(p->rchild);
}
else
{
if(p->lchild==NULL)
exchange(p->rchild);
else
exchange(p->lchild);
}
return OK;
}
}
void main()
{
BiTree T=new BiTNode; //定義一個指向BiTNode結點的指針
int choice;
do{
cout<<"\n";
cout<<"請選擇操作:\n";
cout<<"1.按照先序的次序生成一顆二叉樹\n";
cout<<"2.遞歸算法實現二叉樹的先序遍歷,輸出各結點值\n";
cout<<"3.用非遞歸算法實現二叉樹的遍歷,輸出各結點值\n";
cout<<"4.求度分別爲0、1、2的結點的數目(遞歸算法實現)\n";
cout<<"5.求度分別爲0、1、2的結點的數目(非遞歸算法實現)\n";
cout<<"6.按層次遍歷二叉樹\n";
cout<<"7.求二叉樹的高度(深度)\n";
cout<<"8.判斷是否爲完全二叉樹,輸出\"Yes!\"或\"No!\"\n";
cout<<"9.交換每個結點的左右子樹\n";
cout<<"10.對交換左右子樹後的二叉樹作中序遍歷\n";
cout<<"11.退出\n";
cin>>choice;
switch(choice)
{
case 1:
create_BiTree(T);
break;
case 2:
pre_order_traverse3(T);
break;
case 3:
in_order_traverse2(T);
break;
case 4:
get_node(T);
break;
case 5:
get_node_1(T);
break;
case 6:
level_order_traverse2(T);
break;
case 7:
cout<<"二叉樹的高度爲%d\n"<<height(T)<<endl;
break;
case 8:
if(judge(T)==0)
cout<<"No\n"<<endl;
else
cout<<"Yes\n"<<endl;
break;
case 9:
exchange(T);
break;
case 10:
in_order_traverse(T);
break;
}
}while(choice!=11);
}
二叉樹的幾個相關算法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.