二叉树的先序遍历-递归和非递归算法

版权声明:作者:weizu_cool https://blog.csdn.net/qq_26460841/article/details/84137802

需要实践先序遍历,我们先建立二叉树。这里采用先序序列建立二叉树,不为别的,因为简单。

typedef int ElemType;
typedef struct BiTNode{
	ElemType data;
	struct BiTNode *lchild, *rchild;
}*BiTree, BiTNode;

void CreateBiTreePreOrder(BiTree &T){
	ElemType data;
	cin>>data;
	if(data==-1){
		T=NULL;
	}else{
		T = new BiTNode();//(BiTree)malloc(sizeof(BiTNode));
	}
	if(!T){
		return;
	}else{
		T->data = data;
		CreateBiTreePreOrder(T->lchild);
		CreateBiTreePreOrder(T->rchild);
	}
}

下面是对先序遍历的实现:

① 首先是最简单的先序递归算法

     递归的思想就是将需要重复的步骤分离出来,反复调用,而且下一次的调用需要用到上一次调用的结果。(可以理解为有依赖关系存在)

//递归的先序遍历
void PreOrder(BiTree T){
	if(T){
		cout<<T->data<<" ";
		PreOrder(T->lchild);
		PreOrder(T->rchild);//这里的压栈,只是为了再一次调用上面的函数
	}
}

 ②下面来对递归算法进行非递归实现

 方法一:模拟递归算法的操作过程。

按照先序的思想,可以转化为循环控制。

  • 入栈前,先输出本节点信息;
  • 先左子树一次入栈,直到没有左子树的结点为止;
  • 出栈栈顶元素,然后,找到右子树,继续①②操作,直到栈为空 结点为空。

 在遍历的过程中,进栈、出栈可能会出现栈空的情况,但这时候遍历还没有结束, 故而采用双重判断。

//先序遍历非递归算法
void PreOrder(BiTree bt){
	//需要用到栈,这里简单写作一个数组来用, 最好用链栈,定义好入栈、出栈的操作接口 
	BiTree T = bt;
	BiTree ptr[20]; 
	int top = -1;
	while(T || top!=-1){
		//按照上面的遍历,先输出数据,然后左子树入栈
		while(T){
			cout<<T->data<<" ";
			ptr[++top]=T;
			T=T->lchild; 
		} 
		if(top!=-1){
			T = ptr[top--];
			T = T->rchild;
		} 
	} 
}

方法二:分析先序遍历的特点。

充分考虑先序遍历的特点

  • 1入栈。
  • 1出栈(栈顶元素出栈),输出栈顶元素1,并将1的左右孩子节点入栈;其中右孩子4先入栈,然后左孩子2入栈。(因为,对左边孩子的访问先序遍历先于右孩子,后入栈的先访问)。
  • 2出栈(栈顶元素出栈),输出栈顶元素2,并将2的左右孩子节点入栈,同理5先入栈,3后入栈。
  • 3出栈(栈顶元素出栈),输出栈顶元素33为叶子结点,无孩子,本次无入栈。
  • 5出栈(栈顶元素出栈),输出栈顶元素5
  • 4出栈(最后的栈顶元素出栈),此时 栈空,遍历完毕。
void PreOrder(BiTree bt){
	BiTree ptr[20];
	int top = -1;
	BiTree pt = bt;
	ptr[++top] = pt;
	while(top!=-1){
		pt = ptr[top--];//每次栈顶元素出栈
		cout<<pt->data<<" ";//输出
		if(pt->rchild) 
			ptr[++top] = pt->rchild;
		if(pt->lchild) 
			ptr[++top] = pt->lchild; 
	}
}

 -----------------------------------------分割线------------------------------------------------------------

测试截图:

作者:无涯明月

发文时间:2018-11-16

猜你喜欢

转载自blog.csdn.net/qq_26460841/article/details/84137802