二叉樹中最大搜索子樹和最大搜索子結構
阿新 • • 發佈:2021-01-27
最大的搜尋子樹
輸入描述:
第一行輸入兩個整數 n 和 root,n 表示二叉樹的總節點個數,root 表示二叉樹的根節點。
以下 n 行每行三個整數 fa,lch,rch,表示 fa 的左兒子為 lch,右兒子為 rch。(如果 lch 為 0 則表示 fa 沒有左兒子,rch同理)
ps:節點的編號就是節點的值。
輸入
3 2
2 1 3
1 0 0
3 0 0
輸出
3
基本思路
研究root開頭的子樹是否滿足二叉搜尋樹,滿足那麼直接返回root的大小
否則開始研究root的左右孩子所在子樹。
採取中序遍歷的方式,可以判斷二叉樹是否為搜尋樹,=》滿足升序
程式碼實現
#include<iostream> #include<vector> #include<stack> using namespace std; int ans=0; bool judge(vector<int>&L,vector<int>&R,int root) { //判斷是否為二叉搜尋樹 int pre=0; stack<int> stk; int p=root; while(stk.empty()==false || p!=0) //中序遍歷 { if(p!=0) { stk.push(p); p=L[p]; } else { int now=stk.top(); stk.pop(); if(now<pre) //不滿足 { return false; } pre=now; p=R[now]; } } return true; } int add(vector<int>&L,vector<int>&R,int root) { if(root==0) return 0; else return 1+add(L,R,L[root])+add(L,R,R[root]); } void dfs(vector<int>&L,vector<int>&R,int root) { //首先研究root所在的樹是否滿足要求 if(root==0) return; if(judge(L,R,root)) //滿足要求 { ans=max(ans,add(L,R,root)); return;//不需要再研究子樹 } dfs(L,R,L[root]); dfs(L,R,R[root]); } int main() { int n,root; cin>>n>>root; vector<int> L(n+1); vector<int> R(n+1); for(int i=0;i<n;i++) { int fa,lc,rc; cin>>fa>>lc>>rc; L[fa]=lc; R[fa]=rc; } dfs(L,R, root); cout<<ans<<endl; }
尋找二叉樹中最大搜索子結構
與最大搜索子樹不同,最大子結構可以挑選其中若干的點,使其滿足二叉搜尋樹即可
其特點為,最終樹一定有一個根節點root,那麼問題可以劃歸為在root中尋找,在root的左右子節點中尋找。
首先關鍵函式是研究以root為根節點的最大搜索拓撲結構
//研究node節點是否在以root為根節點的子樹中 bool isBSTNode(vector<int>&L,vector<int>&R,int root,int node) { if(root==0) return false; if(root==node) return true; if(node>root) return isBSTNode(L,R,R[root], node); else return isBSTNode(L,R,L[root], node); } //研究以root祖先節點,cur為根節點的cur的最大搜索子結構 int getSize(vector<int>&L,vector<int>&R,int root,int cur) //注意cur表示當前節點 { if(root==0 || cur==0) return 0; if(!isBSTNode(L,R,root,cur)) //並不在樹木中 return 0; return 1+getSize(L,R, root,L[cur])+getSize(L,R, root,R[cur]); //否則當前節點+左子樹節點最大+右子樹節點最大 }
其關鍵實現為研究一個節點node是否在root開始的搜尋樹結構中。
最終的遞迴函式如下:
void getMax(vector<int>&L,vector<int>&R,int root,int& ans)
{
if(root==0)
return;
ans=max(ans,getSize(L,R,root,root));
getMax(L, R, L[root],ans);
getMax(L, R, R[root],ans);
}
int main()
{
int n,root;
cin>>n>>root;
vector<int> L(n+1);
vector<int> R(n+1);
for(int i=0;i<n;i++)
{
int fa,lc,rc;
cin>>fa>>lc>>rc;
L[fa]=lc;
R[fa]=rc;
}
int ans=1;
getMax(L, R, root, ans);
cout<<ans<<endl;
}