二叉樹高階之尋找一棵二叉樹中的最大二叉搜尋子樹

2021-09-07 10:05:37 字數 2825 閱讀 9378

(規律:在二叉樹中尋找某性質資訊的題目的解題思路:用後序遍歷從小樹建立大樹,還原二叉樹從底層各棵小樹匯聚成完整樹的過程。在建立過程中對每一棵子樹進行判斷尋找,記錄要

查詢性質的所需資訊以及當前子樹的查詢結果向上傳遞(結點作返回值,其他資訊用陣列)。由於樹最終會在根結點彙總,那麼從子樹中的查詢出來的結果就被會傳遞到根結點處了。)

從一棵樹中尋找結點數最多的二叉搜尋子樹,並返回這棵子樹的頭結點。

從題目我們知道以下要求:

1:子樹是二叉搜尋樹,即:左兒子小於父節點,右兒子大於父節點,並且這個性質在整棵樹的任一子樹都成立。——從任一子樹成立,可以得知:一棵二叉搜尋子樹的本身,是從它的子樹也是二叉搜尋樹遞推上來的。因此,我們在遞迴時,從葉到根逐步建立二叉樹的過程中可以每一步都知道當前「根」的子樹是否滿足二叉搜尋樹性質,是則返回這個「根」,否則返回乙個兒結點。對建立二叉樹的過程中每一步的當前「根」,我們都假設左右子樹是二叉搜尋樹,那麼遞迴左子樹時返回的就是左兒子,遞迴右子樹時返回的就是右兒子。因此我們對當前結點作以下判斷:左子樹最大值《當前結點值《右子樹最小值 && 左子樹中的二叉搜尋樹根是左兒子 && 右子樹中的二叉搜尋樹根是是右兒子,則當前結點為「根」的子樹也是二叉搜尋樹,把當前結點返回遞迴上層給他的父節點作判斷使用,否則返回乙個兒結點(只要父節點發現遞迴子樹時返回的不是自己的兒子,即可說明以父節點為根的子樹不是二叉搜尋樹)。

2:二叉搜尋子樹的結點數最大。乙個結點為根的子樹中找結點數最多的二叉搜尋子樹,有兩種情況:

1)當前結點左子樹是二叉搜尋樹,當前結點右子樹是二叉搜尋樹,並滿足 left_max2)如果不滿足第一點,則當前結點為根的結點數最多二叉搜尋子樹是它的左右子樹中結點數最大的那個二叉搜尋子樹,返回左右子樹中結點數最多的二叉搜尋子樹的根結點向上傳遞,更新當前子樹的最大二叉搜尋樹的結點數資訊。

3:極限情況下,整棵樹中沒有一棵二叉搜尋子樹,那麼遞迴到葉子結點的兒結點null時,返回null。然後在逐層向上返回時,因為沒有一棵二叉搜尋子樹,所以null被一直向上傳遞返回。最終得到結果就是null.也就是說:只要有一棵二叉搜尋子樹,那麼它的「根」結點就會被往上傳遞,作為它的眾多祖先們(包括父親)的子樹中的候選最大二叉搜尋子樹直到被拋棄(在某一層時被另一子樹傳上來的最大二叉搜尋子樹取代)。

採用後序遍歷的方式來遍歷二叉樹,對每個結點對進**況1檢查,如果符合則更新子樹最大bst資訊(根結點、結點數)並往上傳遞,如果不是則按照情況2處理。

每層需要採集以下資訊:

1:左子樹中的最大值,左子樹中最小值左子樹的最大二叉搜尋子樹的根結點、左子樹中最大二叉搜尋子樹的結點數目(從下往上建立的二叉搜尋子樹,每處理乙個結點若當前結點為根的樹是二叉搜尋樹,則結點數目=左子樹結點數+右子樹結點數+1.而左右子樹結點數又是從下往上傳來的,從最底層null傳來的是0,每層往上=左子樹結點數+右子樹結點數+1)【遞迴用到的計數,都是從遞迴邊界開始的!所以寫遞迴時一定要先寫好遞迴邊界的返回情況

2:右子樹的同樣4樣資訊。

3:多資訊採集的遞迴,我們採取「結點作返回值,其他資訊用陣列」的方法。

public

treenode getmax(treenode root)

//用陣列記錄子樹中資訊:最大值、最小值、子樹中最大二叉搜尋樹的結點數

int childtree_info=new

int[3];

return

postfind(root,childtree_info);

}public treenode postfind(treenode curr,int

childtree_info)

//遞迴左右子樹,獲取4個資訊

treenode left_maxbst=postfind(curr.left,childtree_info);

int left_maxbst_max=childtree_info[0];

int left_maxbst_min = childtree_info[1];

int left_maxbst_nodesnum = childtree_info[2];

treenode right_maxbst=postfind(curr.right,childtree_info);

int right_maxbst_max = childtree_info[0];

int right_maxbst_min = childtree_info[1];

int right_maxbst_nodesnum = childtree_info[2];

//更新當前結點為根的子樹的最大值、最小值

childtree_info[0]=math.max(right_maxbst_max,curr.val);

childtree_info[1]=math.min(left_maxbst_min,curr.val);

//根據左右子樹遞迴資訊,判斷當前結點為根的子樹性質:如果是二叉搜尋樹則更新最大二叉搜尋子樹的資訊;如果不是,則返回左右子樹中的最大二叉搜尋子樹的資訊

if(left_maxbst==curr.left && right_maxbst==curr.right

&& left_maxbst_maxright_maxbst_min)

else

}

二叉樹 判斷二叉樹是否另一棵二叉樹的子樹

給定兩個二叉樹s和t,判斷t是否為s的子樹。方法一 進行對比時,s不是從根節點開始的,而t是從根節點開始的,因此,可以先計算t的高度,然後在s中找出所有高度和t相同的子樹,然後對比它們是否相同即可。class solution return false public int height treen...

翻轉一棵二叉樹

問題描述 翻轉一棵二叉樹 示例 輸入 4 2 7 1 3 6 9輸出 4 7 2 9 6 3 1 解法 1.用遞迴來解決 2.首先判斷根是不是空 遞迴出口 3.如果不是空則交換左右子數 4.對左子樹進行遞迴 5.對右子樹進行遞迴 definition for a binary tree node.c...

如何判斷一棵二叉樹是完全二叉樹

嚴蔚敏那本教材上的說法 乙個深度為k,節點個數為 2 k 1 的二叉樹為滿二叉樹。這個概念很好理解,就是一棵樹,深度為k,並且沒有空位。首先對滿二叉樹按照廣度優先遍歷 從左到右 的順序進行編號。一顆深度為k二叉樹,有n個節點,然後,也對這棵樹進行編號,如果所有的編號都和滿二叉樹對應,那麼這棵樹是完全...