1. 程式人生 > >劍指Offer36:二叉樹與雙向連結串列的轉換

劍指Offer36:二叉樹與雙向連結串列的轉換

題目:
輸入一顆二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的節點,只能調整樹中節點指標的指向。
例如:

分析過程:
1.指標的調整:
原先指向左子節點的指標,變成指向上一節點的指標
原先指向右子節點的指標,變成指向下一節點的指標

2.調整思路:
對於示例這種基本情況,可以分成三個部分來看,根節點10,左子樹,右子樹,需要做的就是將10與左子樹中的最大值連起來,然後把10與右子樹中的最小值連起來
現在有個問題就是我們並不知道左子樹中的最大值和右子樹中的最小值,如果我們知道就好了。但是想到遞迴,遞迴到左子樹中,如果左子樹已轉換為雙向連結串列,那麼雙向連結串列的最後一個節點就是我們想要的,而右子樹中的第一個節點也是我們想要的

直接上程式碼,程式碼含註釋:(若直接將原書的c程式碼轉換成Java,會有問題。引文方法中的變數引用會導致變數傳不回來。因此設定了一個全域性變數,用來記錄上一節點)
public class Offer36 {

BinaryTreeNode lastNodeInList = null; //用來指向連結串列的上一節點

public BinaryTreeNode convert(BinaryTreeNode root) {
	
	BinaryTreeNode p = root;
	
	convertNode(p);
	
	BinaryTreeNode head = lastNodeInList;
	
	while(head != null && head.m_pLeft != null) { //找到頭節點
		head = head.m_pLeft;
	}
	return head;
}

public void convertNode(BinaryTreeNode node) {
	if(node == null)
		return;
	
	BinaryTreeNode currentNode = node;
	if(currentNode.m_pLeft != null) {
		convertNode(currentNode.m_pLeft);
	}
	
	currentNode.m_pLeft = lastNodeInList; //連線上一節點
	
	if(lastNodeInList != null)
		lastNodeInList.m_pRight = currentNode; //上一節點連線該節點
	
	lastNodeInList = currentNode; //上一節點變為該節點。且左樹排序完成
	
	if(currentNode.m_pRight != null) {
		convertNode(currentNode.m_pRight);
	}
	
}

}