天天看點

二叉樹                                             二叉樹

                                             二叉樹

二叉樹                                             二叉樹

(有關二叉樹的基本定義與存儲結構已在這裡簡要說明--->https://blog.csdn.net/qq_38193883/article/details/98869738)

下面是二叉樹的基本操作:

  • 定義存儲結構:
typedef char Elemtype;
//定義 
typedef struct Tnode{
	Elemtype data;
	struct Tnode *lchild,*rchild;
}Tnode,*Tree;
           
  • 建立二叉樹:
CreateTree(Tree &root){
//僞代碼,不可直接用	
 if(ch=='空指針'){
		root=NULL;
	} 
	else{
		root->data=ch;
		CreateTree(root->lchild);//遞歸周遊建立左子樹
		CreateTree(root->rchild);//遞歸周遊建立右子樹
	}
	
} 
           
  • 二叉樹的周遊: 

                      a.  遞歸周遊:

void DLR(Tree root){
	if(!root){
		return;
	} 
	printf("%c ",root->data);//先(中)(後)序就放最前(中間)(後)面 
	DLR(root->lchild);
	DLR(root->rchild); 
} 
           

                       b.非遞歸(堆棧)周遊

/*   非遞歸中序周遊(堆棧:為了偷懶直接用庫函數了,沒人有意見吧,很明顯。沒有!)
    1.遇到一個節點,就把他限壓入棧,然後周遊它的左子樹
    2.當左子樹周遊結束後 ,從棧頂彈出并通路列印資料 
    3.然後周遊右子樹 
*/ 
void LDRstack(Tree root){
	Tree T;
	stack<Tree> S;
	while(T || !S.empty()) {
		//以下while循環相當于遞歸中的 LDR(root->lchild);
		while(T){
			S.push(T);
			T->lchild;//一直周遊左孩子并入棧 
		}
		
		if(!S.empty())
		{// 若棧不空 
		T=S.top();
	    S.pop();//出棧
		    //中就中在這	
	    printf("%c ",T->data);
		//再用同樣的方式去處理右子樹    
		T=T->rchild;
		} 
  } 
}
/*    層次周遊(這裡星星要用采用隊列) 
		1. 起初:根結點入隊
		2.從隊列中取出一個元素 
		3.通路該節點,該節點帶左右孩子入隊 
		4. 重複 2.->3.->2.->3.->....->直到隊列為空 
*/
void Leveltravel(Tree root){
	queue<Tree> Q; Tree T;
	if(root==NULL){
		return ;
	}
	Q.push(T); 
while(!Q.empty()){
	T=Q.front();
	Q.pop();
	printf("%c ",T->data);
	if(T->lchild){
		Q.push(T->lchild);
	}
	if(T->rchild){
		Q.push(T->rchild);
	}
}
}
           
  • 基于周遊的新功能:
  1.     統計葉子節點的個數
  2.     查找資料為‘X’的節點
  3.     複制二叉樹                    

測試執行個體(AC):(i含魅力注釋i)

#include<stdio.h> 
#include<stdlib.h>
#include<malloc.h>
#include<queue>// 隊列 
#include<stack>//棧

using namespace std;
 
typedef char Elemtype;
//定義 
typedef struct Tnode{
	Elemtype data;
	struct Tnode *lchild,*rchild;
}Tnode,*Tree;

//設定全局變量 
	int count=0;//計數器(統計葉子) 
	int index=0;//字元數組下标 
//測試案例: char str[]="ABDH###E##CF##G##";(由于建立方法采用先序,是以輸入時用先序序列) 
	char str[100];
	  
	
//建立一棵二叉樹
int CreateTree(Tree &root){
	char ch;
	ch=str[index++];
 if(ch=='#'){
		root=NULL;
	} 
	else{
		root=(Tree)malloc(sizeof(Tnode));
		if(!root){
			return -1;
		}
		root->data=ch;
		CreateTree(root->lchild);
		CreateTree(root->rchild);
	}
	return 0;
} 

//用遞歸進行的周遊算法(3種:先序周遊,中序周遊,後序周遊) 
void DLR(Tree root){
	if(!root){
		return;
	} 
	printf("%c ",root->data);//先序就放最前面 
	DLR(root->lchild);
	DLR(root->rchild); 
} 
void LDR(Tree root){
	if(!root){
		return ; 
	} 
	LDR(root->lchild);
	printf("%c ",root->data);//中序就放中間 
	LDR(root->rchild); 
} 
void LRD(Tree root){
	if(!root){
		return;
	} 
	LRD(root->lchild);
	printf("%c ",root->data);//後序就放後面 
	LRD(root->rchild); 
} 

//在周遊算法基礎上拓展的功能:

/*1. 查詢二叉樹中某個值為n的結點*/  
Tree Survey(Tree root,Elemtype n,Tree p){
	if(root){
		if(root->data==n){
			p=root;
			return p;
		}
		else{
			if(Survey(root->lchild,n,p)){
				return Survey(root->lchild,n,p);
			}
			else{
				return Survey(root->rchild,n,p);
			}
			}
		}
	
	else{
		return NULL;
        }
} 
/*2.統計二叉樹中葉子結點的個數(兩種方法)
        a. 使用全局變量Count計數
		b. 利用函數傳回值,Count = Leftcount + Rightcount 
*/ 
int Count1(Tree root){
	if(!root){
		return 0;
	} 
	if((!root->lchild)&&(!root->rchild)){
		count++;
	}
	Count1(root->lchild);
	Count1(root->rchild);
}
int Count2(Tree root){
	if(!root){
		return 0;
	} 
	if((!root->lchild)&&(!root->rchild)){
		return 1; 
			}
	int l=Count2(root->lchild);
	int r=Count2(root->rchild);
	return l+r;
}  
//3. 求二叉樹的深度(後序周遊):求得左、右子樹深度的最大值,然後加 1
int Heigh(Tree root){
	int hl,hr;
	if(!root) return 0;
	else{
		hl=Heigh(root->lchild);
		hr=Heigh(root->rchild);
	return hl>hr?hl+1:hr+1;
	}
}
//4. 複制二叉樹(後序周遊)
Tree Copy(Tree root)//複制二叉樹t
{   Tree newtree;
    if (root==NULL) newtree=NULL;
    else{
	         newtree=(Tree)malloc(sizeof(Tnode)); 
             newtree->data=root->data;
             newtree->lchild=Copy(root->lchild);
             newtree->rchild=Copy(root->rchild);
             } 
return newtree; 
}//結束Copy

int main(){
	Tree T=NULL,p;
	printf("請輸入你要建立的二叉 '檸檬樹' 序列:\n");
	scanf("%s",str); 
	CreateTree(T);
	printf("先序周遊周星星的檸檬樹:\n");
	DLR(T);
    printf("\n中序周遊周星星的檸檬樹:\n");
	LDR(T);
	printf("\n後序周遊周星星的檸檬樹:\n");
	LRD(T);
	p=Survey(T,'B',p);
	printf("\n%c\n",p->data);
    Count1(T);
	printf("葉子節點共有%d個\n",count);
	printf("葉子節點共有%d個\n",Count2(T)); 
	printf("————此檸檬樹共有%d層————\n",Heigh(T));		
return 0;
} 
           
  • 運作結果:

二叉樹                                             二叉樹
  • 正經緻謝:(左圖是享受二叉樹的過程,别問我什麼感受,看右圖(酸爽))

二叉樹                                             二叉樹
二叉樹                                             二叉樹

繼續閱讀