非递归先根遍历

时间:2024-11-07 15:27:57

要使用迭代算法实现对树的先根遍历,必须利用一个堆栈来记录回溯的路径。

将节点p设为根结点

(1)若结点p不为空,则访问结点p,将结点p压入栈中,并将其大儿子结点设为结点p;然后反复执行(1),直至结点p为空。

(2)从栈中弹出一个结点,将其设为结点p,若他有大兄弟结点,则将其大兄弟结点压入栈,且将其大兄弟结点设为结点p;否则,反复执行(2),直至弹出的结点有大兄弟结点或栈空以至无结点可弹出。

(3)反复执行(1),(2),直至栈为空。 


 (以下为“歪理”,可选择不看,仅帮助理解!!!)

如图,树(a)的先根遍历序列为:A B C E F D

(有种从上至左下↙,再向右→向上↑,再向左下↙的趋势的感觉,仅帮助理解记忆!!!)

(因此,我们先找大儿子结点/左指针←,一直有儿子就一直向下↓找,直到没有儿子,找大兄弟/右指针→,一直没有大兄弟结点就一直弹出栈一直找(循环(2)),若有大兄弟结点,再向下找这个兄弟结点的大儿子结点/左指针↙(这一步返回到循环(1)······)

/*非递归先根遍历以t为根指针的树*/
template<class T>
void Tree<T>::NorecPreOrder(TreeNode<T>* t) {
	if (t == NULL) return;
	AStack<TreeNode<T>*> s;
	TreeNode<T>* p = t;
	do {
		while (p != NULL) {  //循环(1)
			cout << p->GetData() << endl;  //访问结点p
			s.Push(p);  //结点p入栈
			p = FirstChild(p);
		}
		while (p == NULL && !s.IsEmpty()) {  //循环(2)
			s.Pop(p);
			p = NextBrother(p);
		}
	} while (!s.IsEmpty());  //循环(3)
};