樹的三種遍歷


二叉樹的先序遍歷(遞歸)

遍歷順序:

         1.先訪問根節點
         2.左子樹遞歸調用先序遍歷
         3.右子樹遞歸調用先序遍歷

圖示:

  • 分析:1.輸出根節點A,2.遞歸左子樹,輸出左子樹的根節點B,繼續遍歷左邊輸出C,然后右邊輸出F,然后輸出E
    3.遞歸右子樹,輸出右子樹的根節點C,訪問左邊,輸出G,G的左邊沒了,右邊輸出H,C的左邊遍歷完了,右邊輸出I。

代碼:

void PreOrder(BinTree BT)
{
	if(BT){//如果樹不為空
		cout<<BT->Data;//輸出根節點(先序遍歷:輸出結點代碼在遞歸之前)
		PreOrder(BT->Left);//遞歸左子樹
		PreOrder(BT->Left);//遞歸右子樹
	}
}

結果:

      - A (BDFE) (CGHI)

二叉樹的中序遍歷(遞歸)

遍歷順序:

                    1.中序遍歷其左子樹(遞歸調用)
                    2.訪問根節點
                    3.中序遍歷其右子樹(遞歸調用)

圖示:

  • 分析:1.先訪問左子樹,走到底(左邊沒元素了),輸出當前結點D,往回走,輸出B,遍歷B的右子樹,到底輸出E,然后F。2.此時A的左子樹遍歷完了,輸出A。
    3. 接着遍歷其右子樹,走左邊到底,輸出H,再G,此時C的左邊走完了,輸出C,接着遍歷C的右邊,輸出I。
  • ps:中序遍歷的結果是整棵樹的投影

代碼:

void PreOrder(BinTree BT)
{
	if(BT){//如果樹不為空
		PreOrder(BT->Left);//遞歸左子樹
		cout<<BT->Data;//輸出節點(中序遍歷:輸出結點的代碼在遞歸中間)
		PreOrder(BT->Left);//遞歸右子樹
	}
}

結果:

      -(DBEF)A (GHCI)

二叉樹的后序遍歷(遞歸)

遍歷順序:

                    1.后序遍歷其左子樹(遞歸)
                    2.后序遍歷其右子樹(遞歸)
                    3.訪問根節點

圖示:

  • 分析:1.遍歷左子樹,走到底,輸出D,回到B遍歷右,到E,輸出E,輸出F,輸出B,遍歷A的右,遍歷C的左,輸出H,輸出G,遍歷C的右輸出I,在輸出C,最后輸出根節點A

代碼:

void PreOrder(BinTree BT)
{
	if(BT){//如果樹不為空
		PreOrder(BT->Left);//遞歸左子樹
		PreOrder(BT->Left);//遞歸右子樹
		cout<<BT->Data;//輸出節點(后序遍歷:輸出結點代碼在遞歸之后)
	}
}

結果:

      - (DEFB) (HGIC) A

總結:

  • 不同主要在於輸出語句的位置。

中序遍歷的堆棧實現(非遞歸)

遍歷實現:

     1.遇到一個結點,壓入棧,並遍歷左子樹
     2.遍歷完左子樹,棧頂彈出一個元素
     3.對彈出元素再遍歷其右子樹

實現過程:

  • 首先,把根節點A入棧,訪問左子樹,B入棧,訪問B的左子樹,D,此時到底了,彈出棧頂元素D,B的左子樹遍歷完成,輸出B,遍歷B的右子樹,F入棧,E入棧,E出,

代碼:

void InOrder(BinTree BT) 
{
	BinTree T;
	Stack S = CreatStack(MaxSize);//建立並初始化棧
	while (T || !IsEmpty(S)) {//判斷棧為空否
		while (T) {
			Push(S, T);//進棧
			T = T->Left;//轉到左子樹遍歷
		}
		if (!IsEmpty(S)) {
			T = Pop(S);//出棧
			cout << T->Data;//輸出
			T = T->Right;//轉到右子樹遍歷
		}
	}
}
  • ps: 前序遍歷則只需把輸出語句放在Push()前

  • ps: 后序遍歷則需要將節點倆次入棧,第二次Pop時再輸出,有點復雜,未做深入研究

層次遍歷的隊列實現

  • 層次遍歷:一層一層的遍歷

遍歷順序:

          1.根節點入隊
      2.出隊隊首元素
      3.把出隊元素的左右孩子依次入隊

代碼:


void LeveOrder(BinTree BT)
{
	Queue Q;
	BinTree T;
	if (!BT) return;//若樹為空,直接返回
	Q = CreatQueue(MaxSize);//創建並初始化隊列Q
	AddQ(Q, BT);//加入根節點
	while (!IsEmptyQ(Q)) {
		T = DeleteQ(Q);//出隊操作
		cout << T->Data;
		if (T->Left)
			AddQ(Q, T->Left);//加入左孩子
		if (T->Right)
			AddQ(Q, T->Right);//加入右孩子
	}
}

結果:

      - A BC DFGI EH

兩種遍歷確定唯一的二叉樹(必須含中序遍歷)

  • 若已知先序遍歷順序為:a bcdefghij和中序遍歷順序為:cbed a hgijf

求解思路:

        1.根據先序第一個節點,確定根節點
        2.在中序中找到a,a左邊的就是左子樹,右邊的為右子樹
        3.依次對左右子樹遞歸可確定出最后的樹


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM