剑指offer中题目:http://ac.jobdu.com/problem.php?pid=1520
输入两颗二叉树A,B,判断B是不是A的子结构。
输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行一个整数n,m(1<=n<=1000,1<=m<=1000):n代表将要输入的二叉树A的节点个数(节点从1开始计数),m代表将要输入的二叉树B的节点个数(节点从1开始计数)。接下来一行有n个数,每个数代表A树中第i个元素的数值,接下来有n行,第一个数Ki代表第i个节点的子孩子个数,接下来有Ki个树,代表节点i子孩子节点标号。接下来m+1行,与树A描述相同。
对应每个测试案例,
若B是A的子树输出”YES”(不包含引号)。否则,输出“NO”(不包含引号)。
7 3 8 8 7 9 2 4 7 2 2 3 2 4 5 0 0 2 6 7 0 0 8 9 2 2 2 3 0 0 1 1 2 0 3 0
YES NO
B为空树时不是任何树的子树。
#include <stdio.h> #include <stdlib.h> #include <queue> #define MAXDATA 0X7FFFFFFF #define MAXSIZE 1001 int TreeData[MAXSIZE]; typedef struct SNode { int data; int left; int right; }SNode; SNode* createNode(int vData) { SNode *Node = (SNode*)malloc(sizeof(SNode)); Node->data = vData; Node->left = -1; Node->right = -1; return Node; } void deleteNode(SNode **vNode) { (*vNode)->left = -1; (*vNode)->right = -1; free(*vNode); *vNode = NULL; } void allocNode(SNode *vArray[], int vSize) { int i; for (i = 1; i <= vSize; ++i) { vArray[i] = createNode(MAXDATA); } } void deleteTree(SNode *vTree[], int vSize) { int i; for (i=1; i <= vSize; ++i) { deleteNode(&(vTree[i])); } } void clearTree(SNode *vTree[], int vSize) { int i; for (i=1; i <= vSize; ++i) { vTree[i]->data = MAXDATA; vTree[i]->left = -1; vTree[i]->right = -1; } } void createBinaryTree(SNode *vNode[], int vN) { int i; int NumChld; for (i = 1; i <= vN; ++i) { scanf("%d", &(vNode[i]->data)); } for (i = 1; i <= vN; ++i) { scanf("%d", &NumChld); if (NumChld == 0) continue; else if (NumChld == 1) { scanf("%d", &(vNode[i]->left)); } else if (NumChld == 2) { scanf("%d %d", &(vNode[i]->left), &(vNode[i]->right)); } } } int judgeSubRoot(int vRootBegin, SNode *vTreeRoot[], int vSubBegin, SNode *vSubRoot[]) { int LeftFlag; int RightFlag; if (vSubBegin == -1) return 1; if (vRootBegin == -1) return 0; if (vTreeRoot[vRootBegin]->data == vSubRoot[vSubBegin]->data) { LeftFlag = judgeSubRoot(vTreeRoot[vRootBegin]->left, vTreeRoot, vSubRoot[vSubBegin]->left, vSubRoot); if (!LeftFlag) return 0; RightFlag = judgeSubRoot(vTreeRoot[vRootBegin]->right, vTreeRoot, vSubRoot[vSubBegin]->right, vSubRoot); if (!RightFlag) return 0; return 1; } else return 0; } int isSubTree(SNode *vTreeRoot[], SNode *vSubRoot[]) { if (vSubRoot[1]->data == MAXDATA || vTreeRoot[1]->data == MAXDATA) return 0; std::queue<int> Que; int Index; int Flag; Que.push(1); while(!Que.empty()) { Index = Que.front(); Que.pop(); if (vTreeRoot[Index]->data == vSubRoot[1]->data) { Flag = judgeSubRoot(Index, vTreeRoot, 1, vSubRoot); if (Flag) return 1; } if (vTreeRoot[Index]->left != -1) Que.push(vTreeRoot[Index]->left); if (vTreeRoot[Index]->right != -1) Que.push(vTreeRoot[Index]->right); } return 0; } int main() { int M; int N; SNode *TreeRoot[MAXSIZE]; SNode *SubRoot[MAXSIZE]; allocNode(TreeRoot, MAXSIZE-1); allocNode(SubRoot, MAXSIZE-1); while (scanf("%d %d", &N, &M) != EOF) { createBinaryTree(TreeRoot, N); createBinaryTree(SubRoot, M); if (isSubTree(TreeRoot, SubRoot)) { printf("YES\n"); } else { printf("NO\n"); } clearTree(TreeRoot, MAXSIZE-1); clearTree(SubRoot, MAXSIZE-1); } deleteTree(TreeRoot, MAXSIZE-1); deleteTree(SubRoot, MAXSIZE-1); return 0; } /************************************************************** Problem: 1520 User: Language: C++ Result: Accepted Time:10 ms Memory:1056 kb ****************************************************************/