劍指offer---樹的子結構

鑑於二叉樹的子樹及二叉樹的子結構問題,現總結如下:

什麼是二叉樹的子結構及子樹?

子樹的意思是包含了一個結點,就得包含這個點下的所有節點,一棵大小爲n的二叉樹有n個子樹,就是分別以每個點爲根的子樹。子結構的意思是包含了一個點,可以只取左子樹或者右子樹,或者都不取。

1、輸入兩棵二叉排序樹A,B,判斷B是不是A的子樹。(ps:我們約定空樹不是任意一個樹的子樹)

二叉排序樹,又稱爲二叉查找樹,它或是一棵空樹,或是一棵具有以下性質的樹:

1)若它的左子樹不空,則左子樹上所有結點的值都小於它的根結點的值;

2)若它的右子樹不空,則右子樹上所有結點的值都小於它的根結點的值;

3)它的左右子樹也分別爲二叉排序樹。

分析:其一、A、B是二叉搜索樹,說明樹中每個點的值都大於左孩子結點的值,並且小於右孩子點的值。

其二、判斷是不是子樹,說明在樹A中找到和樹B的根結點對應的結點後,該結點下面所有的結點都應該是一致的。

struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};
bool IsSametree(TreeNode* pRoot1,TreeNode* pRoot2)
        {
        if(pRoot1==NULL&&pRoot2 == NULL)//同時達到葉子結點
            return true;
        else
            return false;
        if(pRoot1->val == pRoot2->val)
            return IsSametree(pRoot1->left,pRoot2->left)&&IsSametree(pRoot1->right,pRoot2->right);
        else
            return false;
    }
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        if(pRoot2 == NULL)
            return false;
        else if(pRoot1 == NULL)
            return false;
        if(pRoot1->val == pRoot2->val)
            return IsSametree(pRoot1,pRoot2);
        if(pRoot1->val > pRoot2->val)
            return HasSubtree(pRoot1->left,pRoot2);
        if(pRoot1->val < pRoot2->val)
           return HasSubtree(pRoot1->right,pRoot2);
    }
調用的函數爲HasSubtree,由於A、B爲二叉排序樹,所以可以根據值來判斷下一步是從A的左子樹還是右子樹來尋找,如果沒有知識單純的二叉樹,可以將值判斷的兩行代碼用或的關係語句代替,詳見下面代碼。

2、

題目描述

輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)

首先仔細看題目,其一、普通的二叉樹,沒有別的功能;其二、子結構,可以是A樹的任意一部分。

分析可能性,還是依照上面的思路來寫代碼,但是要有一些改變。首先,遞歸返回的條件不一樣,當B到達了葉子結點,但是A沒有到葉子結點,也是正確的,這是和上題不一樣的地方。但是如果A先到葉子結點,就肯定不對,返回false。再者,因爲不是二叉排序樹,所以結點的值沒有限制,如果不同的結點有相同的值,這就要注意了!可能找到和B根結點一樣的值,但是從該結點往下查看,發現結點沒有對應,不要直接返回false!因爲可能有別的結點有相同的值,從該結點往下和B一樣!此時要設置一個標誌位,當是子結構是返回true,當不是子結構時返回false,此時再去搜索A的下一個結點,繼續判斷。

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    bool issubTree(TreeNode* pRootA,TreeNode* pRootB){
        if(!pRootB)//B先到達葉節點
            return true;
        else if(!pRootA)//A先到達葉節點,B不可能是A的子結構
            return false;
        if(pRootB->val==pRootA->val)
            return issubTree(pRootA->left,pRootB->left)&&issubTree(pRootA->right,pRootB->right);
        else return false;
    }
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2){
        if(!pRoot2)
            return false;
        else if(!pRoot1)
            return false;
        bool flag=false;
        if(pRoot1->val==pRoot2->val)
            flag=issubTree(pRoot1,pRoot2);
        if(!flag)
            flag=HasSubtree(pRoot1->left,pRoot2)||HasSubtree(pRoot1->right,pRoot2);
        return flag;
    }
};

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