PTA 數據結構 二叉樹的非遞歸遍歷 pintia

PTA 二叉樹的非遞歸遍歷

這一題寫的我快要吐了,講述一下心酸歷程。

6-3 二叉樹的非遞歸遍歷 (10 分)
本題要求用非遞歸的方法實現對給定二叉樹的 3 種遍歷。

函數接口定義:
void InorderTraversal( BinTree BT );
void PreorderTraversal( BinTree BT );
void PostorderTraversal( BinTree BT );
其中BinTree結構定義如下:


typedef struct TNode Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
int flag;
};
要求 3 個函數分別按照訪問順序打印出結點的內容,格式爲一個空格跟着一個字符。


此外,裁判程序中給出了堆棧的全套操作,可以直接調用。


裁判測試程序樣例:
#include <stdio.h>
#include <stdlib.h>
typedef enum { false, true } bool;


typedef char ElementType;
typedef struct TNode Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
int flag;
};


/
------堆棧的定義-------
/
typedef Position SElementType;
typedef struct SNode PtrToSNode;
struct SNode {
SElementType Data;
PtrToSNode Next;
};
typedef PtrToSNode Stack;


/
裁判實現,細節不表 /
Stack CreateStack();
bool IsEmpty( Stack S );
bool Push( Stack S, SElementType X );
SElementType Pop( Stack S ); /
刪除並僅返回S的棧頂元素 /
SElementType Peek( Stack S );/
僅返回S的棧頂元素 /
/
----堆棧的定義結束-----/


BinTree CreateBinTree(); /
裁判實現,細節不表 /
void InorderTraversal( BinTree BT );
void PreorderTraversal( BinTree BT );
void PostorderTraversal( BinTree BT );


int main()
{
BinTree BT = CreateBinTree();
printf(“Inorder:”); InorderTraversal(BT); printf("\n");
printf(“Preorder:”); PreorderTraversal(BT); printf("\n");
printf(“Postorder:”); PostorderTraversal(BT); printf("\n");
return 0;
}
/
你的代碼將被嵌在這裏 */
輸入樣例:
如圖
在這裏插入圖片描述


輸出樣例:
Inorder: D B E F A G H C I
Preorder: A B D F E C G H I
Postorder: D E F B H G I C A

        這道題目簡直是喪盡天良,慘絕人寰。


        一開始題目看錯了,以爲就是簡單的遞歸(沒看見“非”字)遍歷,馬上就莽。一波只過了2個案例,重新審題發現要非遞歸。
        既然是非遞歸,那無非就是棧,一看題目果然有棧。好的,再掃了一眼題目,節點有個int參數flag,突然想起老師上課說的按照相反順序入棧,然後記一個bool,1代表visit過了,0代表沒有,然後馬上又打。打到一半發現這個flag走了一次之後肯定就不是0了,有可能初始化就不是0(恕我沒學好,我也不知道,感覺沒有初始化函數他就會隨機,事實上我並不知道會怎麼樣)。那我還有兩個要遍歷的就走不了。


        遂重寫。換了個思路,顯然先序遍歷是容易的,一個while就能搞定,剩下兩個分別是 左右中 左中右,想到先一直找左,沒有了再根據情況判斷下一個是什麼。
        上代碼,細節不說,看碼。

void InorderTraversal( BinTree BT ){
    Stack s=CreateStack();
    if(BT!=NULL)
        Push(s,BT);
    BinTree now;
    while(!IsEmpty(s)){
        while(Peek(s)->Left!=NULL)
            Push(s,Peek(s)->Left);
        while(!IsEmpty(s)){
            now=Peek(s);
            printf(" %c",now->Data);
            Pop(s);
            if(now->Right!=NULL){
                Push(s,now->Right);
                break;
            }
        }
    }
}

void PreorderTraversal( BinTree BT ){

    Stack s=CreateStack();
   //Push(s,BT);
    BinTree now=BT;
    if(now!=NULL)
        Push(s,now);
    while(!IsEmpty(s)){
        now=Pop(s);
        printf(" %c",now->Data);
        if(now->Right!=NULL)
            Push(s,now->Right);
        if(now->Left!=NULL)
            Push(s,now->Left);
    }
}

void PostorderTraversal( BinTree BT ){
    Stack s=CreateStack();
    if(BT!=NULL)
        Push(s,BT);
    BinTree now=BT,last=NULL;
    while(!IsEmpty(s)){
        while(Peek(s)->Left!=NULL)
            Push(s,Peek(s)->Left);
        while(!IsEmpty(s)){
            now=Peek(s);
            if(now->Right==last||now->Right==NULL){
                printf(" %c",now->Data);
                Pop(s);
                last=now;
            }
            else{
                Push(s,now->Right);
                break;
            }
        }
    }
}


         還有最後一個坑點

         最後一個測試點總是段錯誤,我仔細的看來看去都沒看見野指針之類的,還以爲自己遇到了指針漂移的玄學問題。。。。

最後發現

有個根節點是NULL的測試點。。。

一開始直接就push了根節點,沒想太多。找了半天,加上之前的遞歸寫法,最後一個測試點過了,但是時間迷之巨大。。以爲是大數據,一直沒往根節點爲空那個方向去想,結果在自暴自棄的路上瘋狂亂改。。。????什麼居然過了。。。。。。????



更新一下

我發現我的同學遞歸也過了。。。。然後仔細看了一下自己的。。。函數名直接複製了第一個函數的函數名,導致有兩個函數是錯的。。。下次一定好好檢查

void InorderTraversal( BinTree BT ){
	if(BT==NULL)
		return ;
	InorderTraversal(BT->Left);
	printf(" %c",BT->Data);
	InorderTraversal(BT->Right);
}
void PreorderTraversal( BinTree BT ){
	if(BT==NULL)
		return ;
	printf(" %c",BT->Data);
	PreorderTraversal(BT->Left);
	PreorderTraversal(BT->Right);
}
void PostorderTraversal( BinTree BT ){
	
	if(BT==NULL)
		return ;
	PostorderTraversal(BT->Left);
	PostorderTraversal(BT->Right);
	printf(" %c",BT->Data);
}

這是常規遞歸寫法 。。題目居然不卡遞歸層數。。。

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