二叉树的前序,中序,后序的递归与非递归遍历以及按层遍历

在这总结了下二叉树基本的几种遍历的递归与非递归的方法

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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章