1. 程式人生 > >二叉樹基本功能實現

二叉樹基本功能實現

一、二叉樹的鏈式儲存

用連結串列來表示一顆二叉樹,每個結點由三個域組成,除了資料域,還有兩個指標域,分別用來存放左右孩子的儲存地址。

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;
		}
	}

}