zoukankan      html  css  js  c++  java
  • 递归与非递归二叉树遍历

          前段时间意外收到MS的电面,因为现在做的工作基本上是与音频、音乐信号处理相关,外带互联网全能打杂型。本质上跟计算机纯软件不是太相关。我最后选择了自己比较感兴趣的IMML组面试了一下。

          面试基本上就是英语口语面试和二叉树相关的内容。所以想进微软的同学,这两项基本功要打好基础了。

         笔试的第一题是用非递归的方法遍历二叉树,这个再学校的时候也没有复习到,只用过递归的方法,工作中也没有用到,所以一时半刻也没写准确,回去学习了一下,补习了一下,不过估计过段时间,还是会忘记,呵呵。

         头文件

    typedef struct BiNode
    {
    	int value;
    	BiNode* pLeftChild;
    	BiNode* pRightChild;
    	int state;
    };
    
    typedef BiNode* BiTree;
    
    void CreateBiTree1(BiNode **root);
    void LayerPrint(BiNode *root);
    void prePrint(BiNode* root);
    void midPrint(BiNode* root);
    void postPrint(BiNode* root);
    
    void prePrint_nonRecusive(BiNode* root);
    void midPrint_nonRecusive(BiNode* root);
    void postPrint_nonRecusive(BiNode* root);
    

      源文件

    #include "CreateBiTree.h"
    #include <malloc.h>
    #include <stdio.h>
    #include <stack>
    #include <queue>
    using namespace std;
    
    void CreateBiTree1(BiNode **root)//递归形式,先序生成树
    {
    	int   input;
    	scanf("%d", &input);
    	if(input == -1)
    	{
    		return ;
    	}
    	*root = (BiNode*) malloc(sizeof(BiNode));//根
    	(*root)->pLeftChild = NULL;
    	(*root)->pRightChild = NULL;
    	(*root)->value = input; 
    	//生成根节点
    	CreateBiTree1( &(*root)->pLeftChild );//生成左子树
    	CreateBiTree1( &(*root)->pRightChild );//生成右子树
    
    }
    
    //逐层遍历,从左到右, 打印出关系图
    void LayerPrint(BiNode *root)
    {
    
    	if(root == NULL)
    	{
    
    	}	
    	queue<BiNode *>  store;
    	store.push(root);
    	int cur_layer_num = store.size();
    
    	while(!store.empty())
    	{
    		
    		int next_layer_num = 0;
    		for(int i = 1; i <= cur_layer_num; i++)
    		{
    			BiNode * temp = store.front();//取出最上层
    			printf("%d ", temp->value);
    			if(temp->pLeftChild != NULL)
    			{
    				store.push(temp->pLeftChild);//保存本节点的各个子节点
    				next_layer_num++;
    			}
    			if(temp->pRightChild != NULL)
    			{
    				store.push(temp->pRightChild);
    				next_layer_num++;
    			}
    			store.pop();//弹出最上层
    		}//本层处理完,下层的子节点也保存了下来
    
    		cur_layer_num = next_layer_num;
    	}
    
    
    }
    
    
    //先序递归
    void prePrint(BiNode* root)
    {
    	if(root == NULL)
    		return;
    	printf("%d ", root->value);
    	prePrint(root->pLeftChild);
    	prePrint(root->pRightChild);
    }
    /*非递归*/
    void prePrint_nonRecusive(BiNode* root)
    {
    	if(root == NULL)
    		return ;
    	BiNode *cur = root;
    	int     state = 0;
    	stack<BiNode*>  store;
    	while(1)
    	{
    		if(!cur)
    		{	
    			//if(cur == root) break;
    			//或者
    			if(store.empty())  break;
    			cur = store.top();//如果当前节点为空,则返回上一层			 
    			state = cur->state;//获取当前节点的状态
    		    store.pop();//弹出该层
    		}
    		else if(state == 0)//打印当前节点,压入栈中
    		{
    			printf("%d ", cur->value);//打印根节点
    			cur->state = 1;
    			store.push(cur);//压入该层的节点
    			cur = cur->pLeftChild;//指向左节点
    			state = 0;//继续往左,打印,添加新的左边节点
    		}
    		else if(state == 1)//转向右边节点
    		{
    			cur->state = 2;//判断以当前节点为根节点,是否已经结束
    			store.push(cur);
    			cur = cur->pRightChild;
                state = 0;
    		}
    		else if(state == 2)//如果,返回上一层节点
    		{			
    			//if(cur == root) break;	
    			//或者
    			if(store.empty())  break;
    
    			cur = store.top();
    			state = cur->state;
    			store.pop();//弹出
    		}		
    
    	}
    }
    
    //中序递归
    void midPrint(BiNode* root)
    {
    	if(root == NULL)
    		return;
    	midPrint(root->pLeftChild);
        printf("%d ", root->value);
    	midPrint(root->pRightChild);
    }
    
    /*非递归*/
    void midPrint_nonRecusive(BiNode* root)//中序遍历
    {
    	if(root == NULL)
    		return;
    	int state =   0; //打印左子树,根,右子树	
    	BiNode*  cur = root;
    	stack<BiNode*>  store;
    	while(1)
    	{
    		if(!cur)//如果为空,则返回上一层
    		{
    			if(cur == root)  break;
    			cur = store.top();
    			state = cur->state;
    			store.pop();
    
    		}
    		if(state == 0)//表示保存本节点入栈, 指向左孩子
    		{
    			cur->state = 1;
    			store.push(cur);//压入栈,表示下次进入时,已当前节点为根节点,完成左边子树状态
    			cur = cur->pLeftChild;//第一次进入左孩子
    			state = 0;
    		}
    		else if(state == 1)//表示已当前节点为根节点,完成左边子树状态
    		{
    			cur->state = 2;
    			store.push(cur);//以其为根节点,右子树完成的状态
    			cur = cur->pRightChild;//第一次进入右孩子
    			state = 0;//添加新节点状态
    		}
    		else if(state == 2)//以当前节点为根节点的树,遍历完成 (完成右子树)
    		{
    			if(root == cur)  break;
    			//打印本层的根节点  
    			printf("%d ", cur->value);
    			cur = store.top();//返回上一层
    			state = cur->state;//恢复该节点的状态
    			store.pop();
    		}
    
    	}
    
    }
    
    
    //后序递归
    void postPrint(BiNode* root)
    {
    	if(root == NULL)
    		return;
    	postPrint(root->pLeftChild);
    	postPrint(root->pRightChild);
    	printf("%d ", root->value);
    }
    /*非递归*/
    void postPrint_nonRecusive(BiNode* root)
    {
    	if(root == NULL)//左子树,右子树,根
    		return;
    	int state = 0;
    	BiNode *cur = root;
    	stack<BiNode*>  store;
    	while(1)
    	{
    		if(!cur)//返回上一层
    		{
    			cur = store.top();
    			state = cur->state;//恢复出栈
    			store.pop();
    		}
    		else if(state == 0)//保存当前节点,进入左子树
    		{
    			cur->state = 1;
    			store.push(cur);
    			cur = cur->pLeftChild;
    			state = 0;//继续往左遍历
    		}
    		else if(state == 1)//表示以当前节点为根节点,完成左子树,进入到右子树
    		{
    			cur->state = 2;
    			store.push(cur);
    			cur = cur->pRightChild;
    			state = 0;
    		}
    		else if(state == 2)//表示已当前节点为根的树,遍历完成
    		{
    			//返回上一层
    			printf("%d ", cur->value);
    			if(cur == root)  break;			
    			cur = store.top();	
    			state = cur->state;
    			store.pop();
    		}
    
    
    
    	}
    
    
    
    }
    

      

    测试文件:

    // BiTree.cpp : 定义控制台应用程序的入口点。
    //
    #include"CreateBiTree.h"
    #include<stdio.h>
    /*
    8
    / 
    / 
    6 10
    /  / 
    5 7 9 11
    */
    
    int main(int argc, char* argv[])
    {
    BiNode* root;
    printf("输入数据:
    ");
    CreateBiTree1(&root);
    //输入 8,6,5,(继续往左)-1(返回上一层状态),(向右)-1(返回上一层),7,(向左)-1(返回上一层状态),(向右)-1(返回上一层),10,9,(向左)-1(返回上一层),(向右)-1(返回上一层),11,-1,-1
    printf("层次打印:
    ");
    LayerPrint(root);	
    printf("
    先序打印:
    ");
    prePrint(root);
    printf("
    中序打印:
    ");
    midPrint(root);
    printf("
    后序打印:
    ");
    postPrint(root);
    
    /*非递归版本*/
    printf("
    非递归,先序打印:
    ");
    prePrint_nonRecusive(root);
    printf("
    非递归,中序打印:
    ");
    midPrint_nonRecusive(root);
    printf("
    非递归,后序打印:
    ");
    postPrint_nonRecusive(root);
    
    return 0;
    }
    

      

  • 相关阅读:
    mybatis plus 获取新增实体的主键
    通过 Feign 进行文件上传
    mybatis plus 更新值为null的字段
    idea 配置 service 服务,多模块同时启动
    通过设置 Chrome 解决开发调用跨域问题
    xargs 命令教程
    我的Windows 10 垃圾清理秘诀(不用优化软件)
    BugReport 分析利器 ChkBugReport
    语言与地区简码大全
    linux 将内容强制输出到终端
  • 原文地址:https://www.cnblogs.com/welen/p/4998394.html
Copyright © 2011-2022 走看看