筆試程序題專項----二叉樹模板

特別是 求兩個結點的最低公共祖先最低公共祖先 O(n)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

//定義節點
typedef struct node
{
    struct node *lchild;
    struct node *rchild;
    string data;
}BNode, *BTree; 

string str;
//按照前序順序建立二叉樹
void createBiTree(BTree &T) 
{
    string tstr="O";
    char c;
    cin >> c;
    if('#' == c)             //當遇到 #時,令樹的根節點爲NULL,從而結束該分支的遞歸
        T = NULL;
    else
    {
        T = new BNode;
        tstr[0]=c;
        T->data=tstr;
        createBiTree(T->lchild);
        createBiTree(T->rchild);
    }
}

//前序遍歷二叉樹並打印
void preTraversePrint(BTree T)
{
    if(T)
    {
        cout<<T->data<<" ";
        preTraversePrint(T->lchild);
        preTraversePrint(T->rchild);
    }
}
//中序遍歷
void midTraverse(BTree T,string a1,BTree & p1,string a2, BTree & p2)
{
    if(T)
    {
        midTraverse(T->lchild,a1,p1,a2,p2);
        if(T->data==a1) p1=T;
        if(T->data==a2) p2=T;
        midTraverse(T->rchild,a1,p1,a2,p2);
    }
}
//7 判斷兩棵二叉樹是否結構相同
bool treeCompare(BTree T1,BTree T2)
{
	if(T1==NULL && T2==NULL)
	{
		return true;
		
	}else if(T1!=NULL&&T2==NULL||T1==NULL&&T2!=NULL)
	{
		return false;
	}else if(T1!=NULL && T2!=NULL)
	{
		return treeCompare(T1->lchild,T2->lchild) && treeCompare(T1->rchild,T2->rchild);
	}
	
}
//求兩個結點的最低公共祖先最低公共祖先,即 LCA(Lowest Common Ancestor)//
//複雜性和 n 同樣數量級 
BTree FindLCA(BTree T, BTree target1, BTree target2)
{
    if (T == NULL)
        return NULL;
    //cout<<"vist"<<T->data<<endl;    
    if (T == target1 || T == target2)
        return T;
  
    BTree left = FindLCA(T->lchild, target1, target2);
    BTree right = FindLCA(T->rchild, target1, target2);
    if (left && right)  // 分別在左右子樹
        return T;
  
    return left ? left : right;  // 都在左子樹或右子樹
}

//10 求任意兩結點距離
//首先找到兩個結點的 LCA,然後分別計算 LCA 與它們的距離,最後相加即可。

int FindLevel(BTree node, BTree target)
{
    if (node == NULL)
        return -1;
    if (node == target)
        return 0;
  
    int level = FindLevel(node->lchild, target);  // 先在左子樹找
    if (level == -1)
        level = FindLevel(node->rchild, target);  // 如果左子樹沒找到,在右子樹找
  
    if (level != -1)  // 找到了,回溯
        return level + 1;
  
    return -1;  // 如果左右子樹都沒找到
}

int DistanceNodes(BTree node, BTree target1,BTree target2)
{
    BTree lca = FindLCA(node, target1, target2);  // 找到最低公共祖先結點
    int level1 = FindLevel(lca, target1); 
    int level2 = FindLevel(lca, target2);
  
    return level1 + level2;
}
//11 找出二叉樹中某個結點的所有祖先結點
bool FindAllAncestors(BTree node, BTree target)
{
	if(node==NULL) 
	{  
	   return false;
	}
	if(node==target)
	{
		return true;
	}
	else
	{
		bool res=FindAllAncestors(node->lchild,target)|| FindAllAncestors(node->rchild,target);
		if(res)
		{
			cout<<node->data<<" ";
			return true;
		}
		else 
		return false;
	}
}
//到葉節點的路徑和爲固定值 
void pathsum(BTree T,int cur,int sum,int a[],int level)
{
	
	if(T->lchild==NULL&&T->rchild==NULL)
	{
	    cout<<cur<<" "<<T->data<<" "<<cur+T->data[0]-'0'<<endl;
		if(cur+T->data[0]-'0'==sum)
		{
			a[level]=T->data[0]-'0';
			for(int i=0;i<=level;i++)
			{
				cout<<a[i]<<" ";
			}
			cout<<endl;
		}
	}
	if(T->lchild!=NULL)
	{
		a[level]=T->data[0]-'0';
		pathsum(T->lchild,cur+a[level],sum,a,level+1);
	}
	if(T->rchild!=NULL)
	{
		a[level]=T->data[0]-'0';
		pathsum(T->rchild,cur+a[level],sum,a,level+1);
	}
	
}
int main() {
    
    BTree root1,root2,root;
    /*//判斷兩棵二叉樹是否結構相同
    createBiTree(root1); // *+a##b##*c##-#d##
    createBiTree(root2); // *+a##b##*c##-##
    cout<<treeCompare(root1,root1)<<endl;
    cout<<treeCompare(root1,root2)<<endl;;
    */
    BTree T1,p1,p2;
    createBiTree(T1); // 123##45##6##7#8#9A##B##
    preTraversePrint(T1);
    midTraverse(T1,"5",p1,"6",p2);
    cout<<endl;
    
    root=FindLCA(T1,p1,p2);
	cout<<"LCA( " +p1->data<<" , "<<p2->data<<" )=";
    if(root!=NULL) cout<<root->data<<endl; 
    else cout<<" -1 "<<endl; 
    
    int dis=DistanceNodes(T1,p1,p2);
    cout<<"節點之間距離:"<<dis<<endl;
    cout<<"節點之間距離:"<<endl;
	FindAllAncestors(T1,p1);
	
	int sum=35;
	int a[100];
	cout<<endl<<"是否存在路徑和"<<endl;
	pathsum(T1,0,sum,a,0);
}

 

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