当前位置:   article > 正文

PTA二叉树练习_输入的第一行给出两个正整数:待查询的结点对数 m(≤ 1 000)和二叉搜索树中结点个

输入的第一行给出两个正整数:待查询的结点对数 m(≤ 1 000)和二叉搜索树中结点个

7-1 树的同构

给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。

fig1.jpg

图1

图2

现给定两棵树,请你判断它们是否是同构的。

输入格式:

输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号);随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。注意:题目保证每个结点中存储的字母是不同的

输出格式:

如果两棵树是同构的,输出“Yes”,否则输出“No”。

输入样例1(对应图1):

  1. 8
  2. A 1 2
  3. B 3 4
  4. C 5 -
  5. D - -
  6. E 6 -
  7. G 7 -
  8. F - -
  9. H - -
  10. 8
  11. G - 4
  12. B 7 6
  13. F - -
  14. A 5 1
  15. H - -
  16. C 0 -
  17. D - -
  18. E 2 -

输出样例1:

Yes

输入样例2(对应图2):

  1. 8
  2. B 5 7
  3. F - -
  4. A 0 3
  5. C 6 -
  6. H - -
  7. D - -
  8. G 4 -
  9. E 1 -
  10. 8
  11. D 6 -
  12. B 5 -
  13. E - -
  14. H - -
  15. C 0 2
  16. G - 3
  17. F - -
  18. A 1 4

输出样例2:

No

代码如下:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef struct node{
  4. char data;
  5. int left,right;
  6. }Node;
  7. int N;
  8. void in(Node* n){
  9. for(int i=0;i<N;i++){
  10. cin>>n[i].data;
  11. char left,right;
  12. cin>>left>>right;
  13. if(left=='-')
  14. n[i].left=-1;
  15. else if(left>='0'&&left<='9')
  16. n[i].left=left-'0';
  17. if(right=='-')
  18. n[i].right=-1;
  19. else if(right>='0'&&right<='9')
  20. n[i].right=right-'0';
  21. }
  22. }
  23. int judge(Node* n1,Node* n2){
  24. int flag=1;
  25. for(int i=0;i<N;i++){
  26. for(int j=0;j<N;j++){
  27. if(n1[i].data==n2[j].data){
  28. if(n1[n1[i].left].data==n2[n2[j].left].data){
  29. if(n1[n1[i].right].data!=n2[n2[j].right].data){
  30. flag=0;
  31. return flag;
  32. }
  33. }
  34. else if(n1[n1[i].left].data==n2[n2[j].right].data){
  35. if(n1[n1[i].right].data!=n2[n2[j].left].data){
  36. flag=0;
  37. return flag;
  38. }
  39. }
  40. else{
  41. flag=0;
  42. return flag;
  43. }
  44. }
  45. }
  46. }
  47. return flag;
  48. }
  49. int main(){
  50. cin>>N;
  51. Node n1[N],n2[N];
  52. in(n1);
  53. cin>>N;
  54. in(n2);
  55. if(N==1&&n1[0].data==n2[0].data){
  56. cout<<"Yes";
  57. return 0;
  58. }
  59. else if(N==1&&n1[0].data!=n2[0].data){
  60. cout<<"No";
  61. return 0;
  62. }
  63. int flag=judge(n1,n2);
  64. if(flag) cout<<"Yes";
  65. else cout<<"No";
  66. return 0;
  67. }

7-2 二叉搜索树的结构

二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。(摘自百度百科)

给定一系列互不相等的整数,将它们顺次插入一棵初始为空的二叉搜索树,然后对结果树的结构进行描述。你需要能判断给定的描述是否正确。例如将{ 2 4 1 3 0 }插入后,得到一棵二叉搜索树,则陈述句如“2是树的根”、“1和4是兄弟结点”、“3和0在同一层上”(指自顶向下的深度相同)、“2是4的双亲结点”、“3是4的左孩子”都是正确的;而“4是2的左孩子”、“1和3是兄弟结点”都是不正确的。

输入格式:

输入在第一行给出一个正整数N(≤100),随后一行给出N个互不相同的整数,数字间以空格分隔,要求将之顺次插入一棵初始为空的二叉搜索树。之后给出一个正整数M(≤100),随后M行,每行给出一句待判断的陈述句。陈述句有以下6种:

  • A is the root,即"A是树的根";

  • A and B are siblings,即"AB是兄弟结点";

  • A is the parent of B,即"AB的双亲结点";

  • A is the left child of B,即"AB的左孩子";

  • A is the right child of B,即"AB的右孩子";

  • A and B are on the same level,即"AB在同一层上"。

题目保证所有给定的整数都在整型范围内。

输出格式:

对每句陈述,如果正确则输出Yes,否则输出No,每句占一行。

输入样例:

  1. 5
  2. 2 4 1 3 0
  3. 8
  4. 2 is the root
  5. 1 and 4 are siblings
  6. 3 and 0 are on the same level
  7. 2 is the parent of 4
  8. 3 is the left child of 4
  9. 1 is the right child of 2
  10. 4 and 0 are on the same level
  11. 100 is the right child of 3

输出样例:

  1. Yes
  2. Yes
  3. Yes
  4. Yes
  5. Yes
  6. No
  7. No
  8. No

代码如下:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef struct node{
  4. int data;
  5. int father=-1;
  6. int left=-1;
  7. int right=-1;
  8. int level=1;
  9. }Node;
  10. void intree(Node* n,int gen,int ru){
  11. if(n[ru].data<n[gen].data){
  12. if(n[gen].left==-1){
  13. n[gen].left=ru;
  14. n[ru].father=gen;
  15. n[ru].level=n[gen].level+1;
  16. }
  17. else
  18. intree(n,n[gen].left,ru);
  19. }
  20. else if(n[ru].data>n[gen].data){
  21. if(n[gen].right==-1){
  22. n[gen].right=ru;
  23. n[ru].father=gen;
  24. n[ru].level=n[gen].level+1;
  25. }
  26. else
  27. intree(n,n[gen].right,ru);
  28. }
  29. }
  30. int main(){
  31. int N;
  32. cin>>N;
  33. Node n[N];
  34. cin>>n[0].data;
  35. for(int i=1;i<N;i++){
  36. cin>>n[i].data;
  37. intree(n,0,i);
  38. }
  39. int M;
  40. cin>>M;
  41. string s;
  42. M++;
  43. while(M--){
  44. int a,b,c,d,flag=0;
  45. getline(cin,s);
  46. if(s.find("root")!=s.npos){
  47. sscanf(s.c_str(),"%d is the root",&a);
  48. if(n[0].data==a) cout<<"Yes"<<endl;
  49. else cout<<"No"<<endl;
  50. }
  51. else if(s.find("siblings")!=s.npos){
  52. sscanf(s.c_str(),"%d and %d are siblings",&a,&b);
  53. for(int i=0;i<N;i++){
  54. if(n[i].data==a)
  55. c=i;
  56. if(n[i].data==b)
  57. d=i;
  58. }
  59. if(n[c].father==n[d].father) cout<<"Yes"<<endl;
  60. else cout<<"No"<<endl;
  61. }
  62. else if(s.find("parent")!=s.npos){
  63. sscanf(s.c_str(),"%d is the parent of %d",&a,&b);
  64. for(int i=0;i<N;i++){
  65. if(n[i].data==a){
  66. c=i;
  67. flag+=1;
  68. }
  69. if(n[i].data==b){
  70. d=i;
  71. flag+=1;
  72. }
  73. }
  74. if((n[d].father==c)&&(flag==2)) cout<<"Yes"<<endl;
  75. else cout<<"No"<<endl;
  76. }
  77. else if(s.find("left")!=s.npos){
  78. sscanf(s.c_str(),"%d is the left child of %d",&a,&b);
  79. for(int i=0;i<N;i++){
  80. if(n[i].data==a)
  81. c=i;
  82. if(n[i].data==b)
  83. d=i;
  84. }
  85. if(n[d].left==c) cout<<"Yes"<<endl;
  86. else cout<<"No"<<endl;
  87. }
  88. else if(s.find("right")!=s.npos){
  89. sscanf(s.c_str(),"%d is the right child of %d",&a,&b);
  90. for(int i=0;i<N;i++){
  91. if(n[i].data==a)
  92. c=i;
  93. if(n[i].data==b)
  94. d=i;
  95. }
  96. if(n[d].right==c) cout<<"Yes"<<endl;
  97. else cout<<"No"<<endl;
  98. }
  99. else if(s.find("level")!=s.npos){
  100. sscanf(s.c_str(),"%d and %d are on the same level",&a,&b);
  101. for(int i=0;i<N;i++){
  102. if(n[i].data==a)
  103. c=i;
  104. if(n[i].data==b)
  105. d=i;
  106. }
  107. if(n[c].level==n[d].level) cout<<"Yes"<<endl;
  108. else cout<<"No"<<endl;
  109. }
  110. }
  111. return 0;
  112. }

7-3 二叉搜索树的最近公共祖先

给定一棵二叉搜索树的先序遍历序列,要求你找出任意两结点的最近公共祖先结点(简称 LCA)。

输入格式:

输入的第一行给出两个正整数:待查询的结点对数 M(≤ 1 000)和二叉搜索树中结点个数 N(≤ 10 000)。随后一行给出 N 个不同的整数,为二叉搜索树的先序遍历序列。最后 M 行,每行给出一对整数键值 U 和 V。所有键值都在整型int范围内。

输出格式:

对每一对给定的 U 和 V,如果找到 A 是它们的最近公共祖先结点的键值,则在一行中输出 LCA of U and V is A.。但如果 U 和 V 中的一个结点是另一个结点的祖先,则在一行中输出 X is an ancestor of Y.,其中 X 是那个祖先结点的键值,Y 是另一个键值。如果 二叉搜索树中找不到以 U 或 V 为键值的结点,则输出 ERROR: U is not found. 或者 ERROR: V is not found.,或者 ERROR: U and V are not found.

输入样例:

  1. 6 8
  2. 6 3 1 2 5 4 8 7
  3. 2 5
  4. 8 7
  5. 1 9
  6. 12 -3
  7. 0 8
  8. 99 99

输出样例:

  1. LCA of 2 and 5 is 3.
  2. 8 is an ancestor of 7.
  3. ERROR: 9 is not found.
  4. ERROR: 12 and -3 are not found.
  5. ERROR: 0 is not found.
  6. ERROR: 99 and 99 are not found.

代码如下:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef struct TNode{
  4. int data;
  5. struct TNode* left=NULL,*right=NULL;
  6. }TNode,*BinTree;
  7. void in(BinTree& BST,int n){
  8. if(BST==NULL){
  9. BST=new TNode;
  10. BST->data=n;
  11. }
  12. else{
  13. if(n<BST->data)
  14. in(BST->left,n);
  15. else if(n>BST->data)
  16. in(BST->right,n);
  17. }
  18. }
  19. int findLCA(BinTree BST,int a,int b){
  20. while (1){
  21. if (BST->data>a&&BST->data>b)
  22. BST=BST->left;
  23. else if(BST->data<a&&BST->data<b)
  24. BST=BST->right;
  25. else
  26. break;
  27. }
  28. return BST->data;
  29. }
  30. int main(){
  31. BinTree BST=NULL;
  32. int M,N;
  33. cin>>M>>N;
  34. int n[N];
  35. for(int i=0;i<N;i++){
  36. cin>>n[i];
  37. in(BST,n[i]);
  38. }
  39. int a,b;
  40. while(M--){
  41. int flaga=0,flagb=0;
  42. cin>>a>>b;
  43. for(int i=0;i<N;i++){
  44. if(a==n[i]) flaga=1;
  45. if(b==n[i]) flagb=1;
  46. if(flaga&&flagb) break;
  47. }
  48. if(!flaga&&!flagb)
  49. printf("ERROR: %d and %d are not found.\n",a,b);
  50. else if(!flaga&&flagb)
  51. printf("ERROR: %d is not found.\n",a);
  52. else if(flaga&&!flagb)
  53. printf("ERROR: %d is not found.\n",b);
  54. else{
  55. int find;
  56. find=findLCA(BST,a,b);
  57. if(find==a)
  58. printf("%d is an ancestor of %d.\n",a,b);
  59. else if(find==b)
  60. printf("%d is an ancestor of %d.\n",b,a);
  61. else
  62. printf("LCA of %d and %d is %d.\n",a,b,find);
  63. }
  64. }
  65. return 0;
  66. }

7-4 完全二叉树的层序遍历

一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是完美二叉树。对于深度为 D 的,有 N 个结点的二叉树,若其结点对应于相同深度完美二叉树的层序遍历的前 N 个结点,这样的树就是完全二叉树

给定一棵完全二叉树的后序遍历,请你给出这棵树的层序遍历结果。

输入格式:

输入在第一行中给出正整数 N(≤30),即树中结点个数。第二行给出后序遍历序列,为 N 个不超过 100 的正整数。同一行中所有数字都以空格分隔。

输出格式:

在一行中输出该树的层序遍历序列。所有数字都以 1 个空格分隔,行首尾不得有多余空格。

输入样例:

  1. 8
  2. 91 71 2 34 10 15 55 18

输出样例:

18 34 55 71 2 10 15 91

代码如下:

  1. #include <bits/stdc++.h>
  2. #define N 31
  3. using namespace std;
  4. int result[N];
  5. int postorder[N];
  6. int in = 1;
  7. void dfs(int x, int m){
  8. if(x > m) return;
  9. dfs(x*2, m);
  10. dfs(2*x+1, m);
  11. result[x]=postorder[in++];
  12. }
  13. int main(){
  14. int n;
  15. cin>>n;
  16. for(int i=1;i<=n;i++)
  17. cin>>postorder[i];
  18. dfs(1,n);
  19. cout<<result[1];
  20. for(int i=2;i<=n;i++)
  21. cout<<" "<<result[i];
  22. return 0;
  23. }

7-5 根据后序和中序遍历输出先序遍历

本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。

输入格式:

第一行给出正整数N(≤30),是树中结点的个数。随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。

输出格式:

在一行中输出Preorder: 以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。

输入样例:

  1. 7
  2. 2 3 1 5 7 6 4
  3. 1 2 3 4 5 6 7

输出样例:

Preorder: 4 1 3 2 6 5 7

代码如下:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. struct node{
  4. int data;
  5. node* l,*r;
  6. };
  7. node* buildTree(int len,int* post,int* mid){
  8. node* root=new node;
  9. if(!len) return NULL;
  10. root->data=post[len];
  11. int index;
  12. for(index=1;index<=len;index++)
  13. if(mid[index]==root->data) break;
  14. root->l=buildTree(index-1,post,mid);
  15. root->r=buildTree(len-index,post+index-1,mid+index);
  16. return root;
  17. }
  18. void out(node* root){
  19. if(root){
  20. cout<<" "<<root->data;
  21. out(root->l);
  22. out(root->r);
  23. }
  24. }
  25. int main(){
  26. int n;
  27. cin>>n;
  28. int postorder[n+1],midorder[n+1];
  29. for(int i=1;i<=n;i++)
  30. cin>>postorder[i];
  31. for(int i=1;i<=n;i++)
  32. cin>>midorder[i];
  33. node* root=buildTree(n,postorder,midorder);
  34. cout<<"Preorder:";
  35. out(root);
  36. return 0;
  37. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/233327
推荐阅读
相关标签
  

闽ICP备14008679号