二叉樹的前序,中序,後序的遞歸與非遞歸遍歷以及按層遍歷

在這總結了下二叉樹基本的幾種遍歷的遞歸與非遞歸的方法

1.按層遍歷 

思路:利用隊列先進先出的思想,先讓根節點入隊,然後根節點出隊,接着讓根節點的左右子女依次入隊,然後以此循環。

//按層遍歷,利用隊列 
void printtree(BTNode *root,int n)
{
	int f=0;
	int r=0;      //f爲隊列的頭部標識(直指對頭元素),r爲尾部標識(指向最後一個元素的下一個位置) 
	BTNode *p;
	BTNode **F=(BTNode **)malloc(n*sizeof(BTNode *)); //動態建立一個數組,用來存儲節點指針(即爲一個隊列) 
	r=(r+1)%n;F[r]=root;  //根節點入隊
	while(r!=f)           //r=f,隊列爲空的條件 
	{
		f=(f+1)%n;      // 根節點出隊 
		p=F[f];
		printf("%5d",p->date);
		if(p->left)    //若根的左子女非空,則入隊 
		{
			r=(r+1)%n;
			F[r]=p->left; 
		}
		if(p->right)   //若根的右子女非空,則入隊
		{
			r=(r+1)%n;
			F[r]=p->right;
		} 
		
	} 
} 

 

 

2.前序非遞歸遍歷  

思路:利用棧先進後出的思想,先讓根節點入棧,然後根節點出棧,

           若根節點的左右子女不爲空,則先將右子女壓棧,再將左子女壓棧,然後將此時棧中的棧 頂節點作爲根節點,循環操作。

            如果根節點左右節點爲空,則直接將此時棧中的棧頂節點作爲根節點,循環操作。

//先序非遞歸遍歷 ,利用棧。
void printtree1(BTNode *root,int n)
{
	int top=-1;      //top爲棧頭標識 
	BTNode *p;
	BTNode **F=(BTNode **)malloc(n*sizeof(BTNode *)); //動態建立一個數組,用來存儲節點指針(即爲一個棧)
	top++;         //根壓棧 
	F[top]=root; 
	while(top+1)       //棧不爲空
	{
		top--;                    //根出棧
		p=F[top+1];
		printf("%5d",p->date);
		
		//  注意!!,必須先壓右子女,再壓左子女!!! 
		if(p->right)           //根的右子女若不爲空,則壓棧   
		   F[++top]=p->right;
	    if(p->left)             //根的左子女若不爲空,則壓棧
	       F[++top]=p->left;
	    
	} 
	printf("\n");
} 

 

3.中序非遞歸遍歷

思路:對於任意一個節點p,先將p的左子女從上往下依次壓棧(p=p->left),直到左子女爲空,即p=null

           然後取棧頂結點,出棧,

           將棧頂結點的右子女壓棧

           循環操作,直到棧爲空結束

//中序非遞歸遍 
void printtree3(BTNode *root,int n)
{
	int top=0;      //top爲棧頭標識 
	BTNode *p;
	BTNode **F=(BTNode **)malloc(n*sizeof(BTNode *)); //動態建立一個數組,用來存儲節點指針(即爲一個棧)
	p=root;
	while(p||top)                   //如果p節點不爲空或棧不爲空
	{
		while(p)                     //將p的左子女依次入棧 
		{
			F[++top]=p;
			p=p->left; 
		}
		if(top)
		{
			p=F[top];              
			printf("%5d",p->date);
			top--;
			p=p->right;
		} 
	} 
	printf("\n");
}

 

4後序非遞歸遍歷

思路: 先將根節點壓棧

            若根節點的左右子女都爲空,或者左右子女都已出棧,則根節點出棧

            否則先將右子女壓棧,再將左子女壓棧

            取棧頂結點重複二三操作

 

//後序非遞歸遍歷
void printtree5(BTNode *root,int n)
{
	int top=0;      //top爲棧頭標識 
	BTNode *p;
	BTNode *q=null;
	BTNode **F=(BTNode **)malloc(n*sizeof(BTNode *)); //動態建立一個數組,用來存儲節點指針(即爲一個棧)
	F[++top]=root;     //將根節點入棧 
	while(top)
	{
		p=F[top];
		if((p->left==null&&p->right==null)||(q&&(q==p->left||q==p->right))) 
		{
			top--;
			printf("%5d",p->date);
			q=p;
		}
		else
		{
			if(p->right)
			{
				//p=p->right;     //
				F[++top]=p->right;
			}
			if(p->left)
			{
				//p=p->left;
				F[++top]=p->left;
			}
		}
	}
	printf("\n");
} 

 

5.前,中,後遞歸遍歷

 

 //先序遞歸遍歷
void printtree2(BTNode *root)
{
	if(root)
	{
	
	   printf("%5d",root->date);
	   printtree2(root->left);
	   printtree2(root->right);
   }   
}

//中序遞歸遍歷 
void printtree4(BTNode * root)
{
    if(root)
    {
	printtree4(root->left);
	printf("%5d",root->date);
	printtree4(root->right);
   } 
}


//後序遞歸遍歷 
void printtree6(BTNode * root)
{
    if(root)
    {
	printtree6(root->left);
	printtree6(root->right);
	printf("%5d",root->date);
   } 
}

 

 

完整代碼如下,我順便建立的二叉查找樹

#include<stdio.h>
#include<stdlib.h>
#define null 0

typedef struct Node
{
	int date;
	struct Node * left;
	struct Node * right;
}BTNode;


//建立二叉查找樹 
BTNode *settree(int *a,int n)
{
	BTNode *root,*t,*p,*c;
	int i;
	root=(BTNode *)malloc(sizeof(BTNode));
	root->date=a[0];        //初始化根節點 
	root->left=root->right=null;
	for(i=1;i<n;i++)       //添加其他節點 
	{
		p=(BTNode *)malloc(sizeof(BTNode));
		p->date=a[i];
		p->left=p->right=null;
		t=root;
		while(t)    
		{
			c=t;
			
			if(t->date>p->date)
			{
				t=t->left;
			}
			else
			{
				t=t->right;
			}
		} 
		if(c->date>p->date)
		{
			c->left=p;
		}
		else
		{
			c->right=p;
		}
	}
	return root;
}
//按層遍歷,利用隊列 
void printtree(BTNode *root,int n)
{
	int f=0;
	int r=0;      //f爲隊列的頭部標識(直指對頭元素),r爲尾部標識(指向最後一個元素的下一個位置) 
	BTNode *p;
	BTNode **F=(BTNode **)malloc(n*sizeof(BTNode *)); //動態建立一個數組,用來存儲節點指針(即爲一個隊列) 
	r=(r+1)%n;F[r]=root;  //根節點入隊
	while(r!=f)           //r=f,隊列爲空的條件 
	{
		f=(f+1)%n;      // 根節點出隊 
		p=F[f];
		printf("%5d",p->date);
		if(p->left)    //若根的左子女非空,則入隊 
		{
			r=(r+1)%n;
			F[r]=p->left; 
		}
		if(p->right)   //若根的右子女非空,則入隊
		{
			r=(r+1)%n;
			F[r]=p->right;
		} 
		
	} 
} 

//先序非遞歸遍歷 ,利用棧。
void printtree1(BTNode *root,int n)
{
	int top=-1;      //top爲棧頭標識 
	BTNode *p;
	BTNode **F=(BTNode **)malloc(n*sizeof(BTNode *)); //動態建立一個數組,用來存儲節點指針(即爲一個棧)
	top++;         //根壓棧 
	F[top]=root; 
	while(top+1)       //棧不爲空
	{
		top--;                    //根出棧
		p=F[top+1];
		printf("%5d",p->date);
		
		//  注意!!,必須先壓右子女,再壓左子女!!! 
		if(p->right)           //根的右子女若不爲空,則壓棧   
		   F[++top]=p->right;
	    if(p->left)             //根的左子女若不爲空,則壓棧
	       F[++top]=p->left;
	    
	} 
	printf("\n");
} 

 //先序遞歸遍歷
void printtree2(BTNode *root)
{
	if(root)
	{
	
	   printf("%5d",root->date);
	   printtree2(root->left);
	   printtree2(root->right);
   }   
}

//中序非遞歸遍 
void printtree3(BTNode *root,int n)
{
	int top=0;      //top爲棧頭標識 
	BTNode *p;
	BTNode **F=(BTNode **)malloc(n*sizeof(BTNode *)); //動態建立一個數組,用來存儲節點指針(即爲一個棧)
	p=root;
	while(p||top)                   //如果p節點不爲空或棧不爲空
	{
		while(p)                     //將p的左子女依次入棧 
		{
			F[++top]=p;
			p=p->left; 
		}
		if(top)
		{
			p=F[top];              
			printf("%5d",p->date);
			top--;
			p=p->right;
		} 
	} 
	printf("\n");
}

//中序遞歸遍歷 
void printtree4(BTNode * root)
{
    if(root)
    {
	printtree4(root->left);
	printf("%5d",root->date);
	printtree4(root->right);
   } 
}

//後序非遞歸遍歷
void printtree5(BTNode *root,int n)
{
	int top=0;      //top爲棧頭標識 
	BTNode *p;
	BTNode *q=null;
	BTNode **F=(BTNode **)malloc(n*sizeof(BTNode *)); //動態建立一個數組,用來存儲節點指針(即爲一個棧)
	F[++top]=root;     //將根節點入棧 
	while(top)
	{
		p=F[top];
		if((p->left==null&&p->right==null)||(q&&(q==p->left||q==p->right))) 
		{
			top--;
			printf("%5d",p->date);
			q=p;
		}
		else
		{
			if(p->right)
			{
				//p=p->right;     //
				F[++top]=p->right;
			}
			if(p->left)
			{
				//p=p->left;
				F[++top]=p->left;
			}
		}
	}
	printf("\n");
} 
//後序遞歸遍歷 
void printtree6(BTNode * root)
{
    if(root)
    {
	printtree6(root->left);
	printtree6(root->right);
	printf("%5d",root->date);
   } 
}


int main()
{
	int a[10]={10,6,14,3,8,19,4,7,18,21};
	BTNode *r;
	
	r=settree(a,10);
	printtree(r,10);
	printf("\n");
	printtree1(r,10);
	printtree2(r);
	printf("\n");
	printtree3(r,10);
	printtree4(r);
	printf("\n");
	printtree5(r,10);
	printtree6(r);
	return 0;
}

 


 

 

          

 

 

發佈了37 篇原創文章 · 獲贊 16 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章