算法導論:第10章

10.4-5 O(n)非遞歸O(1)空間遍歷二叉樹樹節點node

轉自http://blog.csdn.net/mishifangxiangdefeng/article/details/7708490ios

採用相似中序遍歷的處理方法,對一個結點,能夠分爲如下幾種狀況數組

1.從父結點進入子結點進行處理函數

(1)若是有左孩子,就處理左孩子spa

(2)返回到本身.net

(3)訪問本身指針

(4)若是有右孩子,就處理右孩子blog

(5)返回到本身的父結點遞歸

2.從左孩子返回,說明左孩子已經處理過,本身還沒訪問,本身的右孩子也沒有處理過,就進行1-(2)ci

3.從右孩子返回,說明左右孩子都已經處理,本身也訪問過,就返回到更上層

4.返回到根結點時,遍歷結束

#include <iostream>
using namespace std;

//二叉樹結點的結構體
struct node
{
	int key;//值
	node *left;//指向左孩子
	node *right;//指向右孩子
	node(){}//默認構造函數
	node(int x):key(x),left(NULL),right(NULL){}//構造函數
};
//樹的結構體
struct tree
{
	node *root;//樹中只有一個指向根結點的指針
	tree():root(NULL){}//構造函數
};
/************10.4-2-遞歸地遍歷訪問二叉樹***************************************/
//輸出訪問某個結點
void Node_Print(node *N)
{
	//訪問當前結點
	cout<<N->key<<' ';
	//遞歸地訪問其左孩子
	if(N->left)
		Node_Print(N->left);
	//遞歸地訪問其右孩子
	if(N->right)
		Node_Print(N->right);
}
//遍歷二叉樹
void Tree_Print(tree *T)
{
	//只孩子訪問根結點,其它結點都在遞歸中訪問了
	Node_Print(T->root);
	cout<<endl;
}
/*************10.4-3-非遞歸地遍歷二叉樹*******************************************/
//把x結點壓入棧S的頂部
void Push(node *S, node x)
{
	S[0].key++;
	S[S[0].key] = x;
}
//彈出棧頂元素並返回
node* Pop(node *S)
{
	if(S[0].key == 0)
		return NULL;
	node *ret = &S[S[0].key];
	S[0].key--;
	return ret;
}
//用非遞歸的方式遍歷二叉樹
void Tree_Print2(tree *T)
{
	//這種方式要藉助一個棧來實現,棧的大小爲樹的深度
	node Stack[15] = {0};//簡單的數組棧,Stack[0]存儲棧頂位置
	node *t = T->root;
	//當處理一個結點時,作以下處理
	while(1)
	{
		//訪問這個結點
		cout<<t->key<<' ';
		//入棧
		Push(Stack, *t);
		//若是有左孩子,下一步處理其左孩子
		if(t->left)
			t = t->left;
		//若是沒有左孩子
		else
		{
			do{
				//彈出棧頂元素
				t = Pop(Stack);
				//若棧中元素已經所有彈出,那麼二叉樹訪問結束了
				if(t == NULL)
				{
					cout<<endl;
					return;
				}
			}
			//若是這個棧頂元素沒有右孩子,則繼續出棧,直到訪問結束或找到一個有右孩子的元素
			while(t->right == NULL);
			//若是這個棧頂元素有右孩子,則訪問其右孩子
			t = t->right;
		}
	}
}
/*input:0=NIL
12 7 3
15 8 0
4 10 0
10 5 9
2 0 0
18 1 4
7 0 0
14 6 2
21 0 0
5 0 0
*/
int main()
{
	//構造一棵樹按照10.4-1
	int i;
	node A[11];//這個數組僅僅用於構造10.4-1中的樹,在遍歷時不使用
	for(i = 1; i <= 10; i++)
	{
		int key, left, right;
		cin>>key>>left>>right;
		A[i].key = key;
		if(left)
			A[i].left = &A[left];
		else A[i].left = NULL;
		if(right)
			A[i].right = &A[right];
		else A[i].right = NULL;
	}
	//生成一棵樹
	tree *T = new tree();
	T->root = &A[6];
	//10.4-2,遞歸方式
	Tree_Print(T);
	//10.4-3,非遞歸方式
	Tree_Print2(T);
	return 0;
}
相關文章
相關標籤/搜索