1. 程式人生 > >如何判斷一棵樹是否為另一棵樹的子結構

如何判斷一棵樹是否為另一棵樹的子結構

前兩天有個 朋友問到了這個這個問題,我很感興趣。

其實策略很簡單,用個佇列儲存母樹以層次遍歷的形式儲存可能的子樹的根節點, 然後對這個佇列進行遍歷,以子樹為主與當前要判斷的根節點經行比對,若遍歷完整個佇列,仍未找到,則該子樹不是所要判斷的母樹的子結構。

PS:其實也不用儲存可能存在的根節點,以前序遍歷的方式對母樹經行遍歷,在遍歷的過程中當前結點與子樹經行比對,若遍歷完整棵母樹仍未找到,則表明當前子樹不是母樹的子結構。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
typedef struct node_s{
  char key;
  struct node_s *lchild,*rchild;
}node;
char bow[50];
int len;

void print_line()
{
    printf("\n\n-------------------------------------------------------------------------------------\n\n");
}

node *create()
{
    node *temp=NULL;

    if(bow[len]!='#')
    {
        temp=(node*)malloc(sizeof(node));
        temp->key=bow[len];
        len++;
        temp->lchild=create();
        temp->rchild=create();
    }
    else
        len++;

    return temp;
}

int sumNode(node *tree)                         //統計樹的節點數
{
    if(!tree)
        return 0;
    else
        return 1+sumNode(tree->lchild)+sumNode(tree->rchild);
}

node **findQueue(node *tree)                     //將可能的根節點儲存在佇列中
{
    int max=sumNode(tree);
    node **queue=(node**)malloc(sizeof(node*));
    int front=0,rear=0;
    node *temp=tree;
    queue[rear++]=temp;

    while(front<rear)
    {
        temp=queue[front++];
        if(temp->lchild)
            queue[rear++]=temp->lchild;
        if(temp->rchild)
            queue[rear++]=temp->rchild;
    }

    return queue;
}

int equalTree(node *parent,node* child)                       //對當前根節點與子樹進行比對
{
    int flag;

    if(parent&&child&&parent->key==child->key)
    {
        flag=1;
        if(child->lchild)
            flag*=equalTree(parent->lchild,child->lchild);
        if(child->rchild)
            flag*=equalTree(parent->rchild,child->rchild);
    }
    else
        flag=0;

    return flag;
}

node *findBegin(node *tree,node *think)
{
    int max=sumNode(tree);
    node **queue=findQueue(tree);
    int flag=0;
    node *index=NULL;
    int i;

    for(i=0;i<max;i++)
    {
        flag=equalTree(queue[i],think);
        if(flag==1)
        {
            index=queue[i];
            break;
        }
    }

    return index;
}

void test()
{
    node *tree;
    node *think;
    node *index;

    print_line();
    printf("輸入母樹:");
    gets(bow);
    tree=create();

    len=0;
    print_line();
    printf("輸入子樹:");
    gets(bow);
    think=create();

    index=findBegin(tree,think);
    if(index==NULL)
    {
        print_line();
        printf("輸入的子樹不是母樹的子結構!");
    }
    else
    {
        print_line();
        printf("輸入的子樹是母樹的子結構,且起點為%c!",index->key);
    }
}

int main()
{
    test();
    print_line();
    system("pause");

    return 0;
}