遞歸與非遞歸創建二叉樹


二叉樹中又有二叉樹,也就是遞歸。因此使用遞歸創建二叉樹是最簡單的。思路很簡單:我們申明一個結構體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;
}  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM