二叉樹中又有二叉樹,也就是遞歸。所以使用遞歸建立二叉樹是最簡單的。思路很簡單:咱們申明一個結構體TREENODE,該結構體有三個成員,分別是Value,LeftChild和RightChild。node
代碼以下:函數
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=調用自身。完事之後返回。blog
代碼以下:遞歸
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。io
若是換作非遞歸的方式建立,就沒有這個問題了。可是非遞歸建立稍微複雜一點點,須要用到棧stack。class
原理很簡單:變量
0、判斷Value是否等於‘#’,若是是:執行第5步;不然:執行第1步原理
一、建立節點二叉樹
二、判斷棧是否爲空,若是爲空:執行第4步;不然:執行第3步static
三、判斷方向是否爲Left,若是是:棧頂元素的左孩子等於第1步建立的節點,執行第4步;不然:棧頂元素的右孩子等於第1步建立的節點,刪除棧頂元素,方向改成左,執行第4步。
四、節點入棧
五、判斷方向是否等於右,若是是:刪除棧頂元素;若是不是:將方向改成右
具體代碼以下:
// 先序建立 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; }