• 递归与非递归创建二叉树


    二叉树中又有二叉树,也就是递归。因此使用递归创建二叉树是最简单的。思路很简单:我们申明一个结构体TREENODE,该结构体有三个成员,分别是Value,LeftChild和RightChild。

    代码如下:

    typedef struct _struct_tree_node
    {
        char m_cData;
        _struct_tree_node* m_pLeftChild;
        _struct_tree_node* m_pRightChild;
    }TREENODE, *LPTREENODE;
    

    首先我们new一个TREENODE,将输入一个值赋给Value,LeftChild=调用自身,RightChild=调用自身。完事以后返回。

    代码如下:

    LPTREENODE RecursionCreateTree(char* pValue)
    {
      if(!pValue || !(*pValue) || *pValue == '#')return NULL;
      static int nIndex = 0;
      
      LPTREENODE pTemp = new TREENODE;
      memset(pTemp, 0, sizeof(TREENODE));
      pTemp->m_cData = *(pValue + nIndex++);
      pTemp->m_pLeftChild = RecursionCreateTree(pValue);
      pTemp->m_pRightChild = RecursionCreateTree(pValue); 
      return pTemp;
    }

    递归创建是不是很简单?哈哈。。。别高兴得太早,这个函数是一次性的喔,也就是说只能创建一颗二叉树,不能创建第二颗。原因就出在了nIndex这个静态变量这里。如果你需要再创建一颗二叉树,那么再创建之前需要将nIndex赋为0。

    如果换做非递归的方式创建,就没有这个问题了。但是非递归创建稍微复杂一点点,需要用到栈stack。

    原理很简单:

    0、判断Value是否等于‘#’,如果是:执行第5步;否则:执行第1步

    1、创建节点

    2、判断栈是否为空,如果为空:执行第4步;否则:执行第3步

    3、判断方向是否为Left,如果是:栈顶元素的左孩子等于第1步创建的节点,执行第4步;否则:栈顶元素的右孩子等于第1步创建的节点,删除栈顶元素,方向改为左,执行第4步。

    4、节点入栈

    5、判断方向是否等于右,如果是:删除栈顶元素;如果不是:将方向改为右

    具体代码如下:

    // 先序创建
    TEMPTYPE bool CBinaryTree<type>::FirstOrderCreate(__in const type* pValue, __in UINT nSize)
    {
    	if (!pValue || !nSize)return false;
    	const type* pTempValue = pValue;
    	stack<LPTREENODE>* pStack = new stack<LPTREENODE>;
    	bool IsDirection = true;// true:左 false:右
    
    	// 创建子节点
    	while (*pTempValue)
    	{
    		while (*pTempValue != m_Make/*m_Make等于‘#’号*/){
    			// 创建子节点
    			auto p = new TREENODE;
    			memset(p, 0, sizeof(TREENODE));
    			p->m_Data = *pTempValue;
    
    			// 挂在左/右节点
    			if (!pStack->empty()){
    				if (IsDirection){// 栈顶左节点
    					pStack->top()->m_pLeftChild = p;
    				}
    				else{// 栈顶右节点,子树创建完成,删除栈顶元素,方向变为左,既创建左节点
    					pStack->top()->m_pRightChild = p;
    					pStack->pop();
    					IsDirection = true;
    				}
    				// 节点入栈
    				pStack->push(p);
    			}
    			else {// 栈空,既跟节点
    				m_pTree = p; 
    				pStack->push(p);
    			}
    			pTempValue++;
    		}
    		pTempValue++;
    		// 如果方向为右,删除栈顶元素;否则方向变为右
    		if (!IsDirection){ pStack->pop();}
    		else IsDirection = false;
    	}
    	delete pStack;
    	return true;
    }  
  • 相关阅读:
    洛谷 P1092 虫食算
    2018.3.25校内互测
    洛谷 P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows
    洛谷 P1879 [USACO06NOV]玉米田Corn Fields
    洛谷 P3052 [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper
    ZJOI Day 2 游记
    editorial-render A
    BZOJ2904
    BZOJ 1600
    构造脚本语言
  • 原文地址:https://www.cnblogs.com/LandyTan/p/8045331.html
Copyright © 2020-2023  润新知