1. 程式人生 > >Java實現樹結構資料的遞迴與非遞迴遍歷

Java實現樹結構資料的遞迴與非遞迴遍歷

樹結構的遞迴與非遞迴的遍歷

遞迴在很多情況下我們都會使用,比如著名的漢諾塔問題、二分查詢等,有時候我們遍歷一棵樹形資料結構的資料也會需要用到遞迴,但並不是絕對。原因是:以遞迴遍歷一棵樹型結構的資料為例,遞迴會不斷的呼叫當前方法,以深度遍歷方式沿著一條支路走到底,然後再回來執行下一條支路。這種情況下在呼叫當前方法之後,編譯器將這個方法的所有引數和返回地址壓入棧中,在這種情況下當前執行緒若又去呼叫了一遍當前這個方法,而當這個支路又足夠深,那麼積攢起來的棧中內容就會越來越多,直到發生記憶體溢位。

因此在樹形資料結構足夠深的時候,我們需要用另一種方法來遍歷這些資料,這種方法是通過寬度遍歷,從樹的頂層開始遍歷,遍歷完這一層後,遍歷下一層,當下一層都遍歷到後再遍歷下一層,依次繼續向下遍歷,這種方式可以用while迴圈來實現。

樹形結構的資料的遞迴遍歷的Java虛擬碼:

// 深度遍歷程式碼
TreeNode parent; // 要遍歷的頂層節點
public void traverse(TreeNode parent) {
	List<TreeNode> childs = getChilds(parent); // parent的所有直接子節點
	if (childs != null) {
		for (child : childs) {
			// ------------
			// 獲取child內容,或其他處理
			// ------------
			traverse(child);
		}	
	}
}
private List<TreeNode> getChilds(TreeNode parent) {
	// 給定父節點獲取直接子節點
}

以下是樹形結構的資料的非遞迴遍歷的Java虛擬碼:

// 寬度遍歷程式碼
TreeNode parent; // 要遍歷的頂層節點
List<TreeNode> childs = getChilds(parent); // parent的所有直接子節點
while (childs != null) {
	List<TreeNode> tempChilds;
	for (child : childs) { // 遍歷子節點
		// ------------
		// 獲取child內容,或其他處理
		// ------------
		if (getChilds(child) != null) {
			tempChilds.add(child);
		}
	}
	childs = tempChilds;
}
private List<TreeNode> getChilds(TreeNode parent) {
	// 給定父節點獲取直接子節點
}

以上內容僅供參考,如有疑問或錯誤,還望提出,大家共同進步。