二叉樹的遍歷(遞歸加迭代)

先定義結點的結構如下:

//二叉樹結點
typedef struct BiTNode{
	//數據
	char data;
	//左右孩子指針
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTreePtr;

後序遍歷最難,先搞後序遍歷。

遞歸:

//後序遍歷
void PostOrder(BiTreePtr T)
{
	if(nullptr != T)
	{
		//訪問左子結點
		PostOrder(T->lchild);
		//訪問右子結點
		PostOrder(T->rchild);
		//訪問根節點
		Visit(T);
	}
}

迭代:

後序遍歷要求在遍歷完左右子樹後,再訪問根。需要判斷根結點的左右子樹是否均遍歷過。因爲相對於左右子結點來說,根結點總是被訪問。所以我們只需要額外再增加一個指針,指向剛剛訪問過的結點即可。只要剛剛訪問過的結點是當前結點的右結點,或者當前結點的右結點爲空,那麼就訪問當前結點。否則,去訪問當前結點的右子結點。

void PostOrder_iteration(BiTreePtr T)  // 後序遍歷的非遞歸    
{    
    std::stack<BiTreePtr> S;    
    BiTreePtr curr = T ;           // 指向當前要檢查的節點  
    BiTreePtr previsited = nullptr;    // 指向前一個被訪問的節點  
    while(nullptr != curr || !S.empty())  // 棧空時結束    
    {    
        while(nullptr != curr)            // 一直向左走直到爲空  
        {    
            S.push(curr);    
            curr = curr->lchild;    
        }    
        curr = S.top();  
        // 當前節點的右孩子如果爲空或者已經被訪問,則訪問當前節點  
        if(nullptr == curr->rchild || curr->rchild == previsited)    
        {    
            cout<<curr->data<<"  ";    
            previsited = curr;    
            S.pop();    
            curr = nullptr;    
        }    
        else  
            curr = curr->rchild;      // 否則訪問右孩子  
    }    
} 


中序遍歷

遞歸:

//中序遍歷
void InOrder(BiTreePtr T){
	if(nullptr != T !){
		//訪問左子結點
		InOrder(T->lchild);
		//訪問根節點
		Visit(T);
		//訪問右子結點
		InOrder(T->rchild);
	}
}
迭代:

void InOrder_iteration(BiTreePtr T)   // 中序遍歷的非遞歸  
{  
    if(nullptr == T)  
        return ;  
		
    BiTreePtr curr = T;    // 指向當前要檢查的節點  
    std::stack<BiTreePtr> s;
	while(nullptr != curr || !s.empty())
	{
		while(nullptr != curr)
		{
			s.push(curr);
			curr = curr->lchild;
		}
		
		curr = s.top();
		s.pop();
		cout<<curr->data<<"  ";
		curr = curr->rchild;
	}
}

前序遍歷

遞歸:

//前序遍歷
void PreOrder(BiTNodePtr T)
{  
    if(nullptr == T)  
        return ;  
	
    printf("%c ", T->data); //輸出數據  
    PreOrder(T->lchild); //遞歸調用,前序遍歷左子樹  
    PreOrder(T->rchild); //遞歸調用,前序遍歷右子樹  
} 
迭代:

void PreOrder_iteration(BiTreePtr T)     //先序遍歷的非遞歸    
{  
    if(nullptr != T)    
        return ;    
    
    std::stack<BiTreePtr> s;  
    s.push(T);  
  
    while(!s.empty())  
    {  
        BiTree temp = s.top();  
        std::cout<<temp->data<<" ";  
        s.pop();  
        if(temp->rchild)  
            s.push(temp->rchild);  
        if(temp->lchild)  
            s.push(temp->lchild);  
    }  
}  
方法二,還是迭代:

void PreOrder_iteration(BiTreePtr T)     //先序遍歷的非遞歸 
{
	if(nullptr != T)  
        return;
		
	std::stack<BiTreePtr> s;
	BiTreePtr curr = T;
	while(nullptr != curr || !s.empty())
	{
		while(nullptr != curr)
		{
			std::cout<<curr->data<<"  ";
			s.push(curr);
			curr = curr->lchild;
		}

		curr = s.top();
		s.pop();
		curr = curr->rchild;
	}
}

最後,還有二叉樹的層次遍歷。對於層次遍歷,類似於圖的廣度優先DFS。這就該用隊列來實現了。

這篇博文寫的太長了,新開一篇來寫層次遍歷及相關變形吧。

http://blog.csdn.net/friendbkf/article/details/50316209

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章