[关闭]
@ysner 2021-11-02T23:59:01.000000Z 字数 5727 阅读 951

燕山楠的Homework 3

数据结构


T1

设该树中度数为的结点有个,度数为的结点有个,以此类推。设总结点个数为
则有



代入,联立以上方程解得
综上,该树的总结点个数为

T2

由于,故第层只可能是完全二叉树的最下两层。
若是倒数第二层,则该层有个非叶子结点,最多对应个倒数第一层的结点。由于树的前层是满的,故树结点个数最多为
若是倒数第一层,由于树的前层是满的,故树节点个数最少为
综上,该完全二叉树的结点个数最多为,最少为

T3

设该树中度数为的结点有个,度数为的结点有个,度数为的结点有个。设总结点个数为
由二叉树性质得,,故由
可得,该二叉树的总结点数至少为

T4

(1)由于,故该树共有层,树的高度为
(2)由于树的结点数为偶数个,且完全二叉树的单支节点数只可能为,所以单支节点数为
(3)由二叉树性质,。代入解得,故叶子结点数为
(4)由于层序编号中非叶子结点一定在叶子结点前面,由非叶子结点个数为,故最小的叶子结点的层序编号为

T5

已知树的先序序列为,中序序列为,后序序列为
(1)由题,,由于不能为空(非空二叉树),故一定为空,即该树的所有结点没有左子树。
(2)由题,,当为空时该式也成立。
综上,满足题目条件的非空二叉树中,所有结点都没有左子树。

T6

能。由于该树是完全二叉树,我们可以根据序列的长度得出树的结点个数,然后直接画出树的形态。最后依据序列里的元素填数,即可唯一确定这棵二叉树。

T7

由题意构造出的哈夫曼树如附图所示。
由图可得,编码0、00不可能对应字母;编码001对应当前字母;前缀为001的编码不可能对应字母;前缀为1、01或000的编码一定对应其他字母(但不一定恰好是1、01、000,因为这个哈夫曼树还可以自叶子节点向外扩展)。
综上,(1)编码0、00和前缀为001的编码不可能对应其他字母;(2)前缀为1、01或000的编码肯定对应其他字母。

T8(核心代码:函数)

本题代码为T8代码。核心代码为函数。
输入的是二叉树对应的括号序列。
ps:检测程序输出结果正确性的方法是,先人工写出树的后序序列,再倒过来。

  1. import java.util.*;//Stack在util里,不在util.Scanner里...
  2. public class hw4_4
  3. {
  4. public static class Node
  5. {
  6. char w;
  7. Node ls,rs;
  8. public Node(){ls=rs=null;}
  9. public Node(char ww){w=ww;ls=rs=null;}
  10. }
  11. public static class BTree//养成在类名前加static的好习惯
  12. {
  13. Node R;//Root,树的根结点
  14. String ans;
  15. public BTree(String str)//函数功能:初始化+根据输入的括号序列建树
  16. {
  17. R=null;
  18. ans="";
  19. Stack<Node> st=new Stack<>();
  20. Node t=null;//变量初始化!
  21. int n=str.length();
  22. boolean flag=true;//标识当前栈顶元素左孩子是否已处理过/跳过
  23. for(int i=0;i<n;i++)
  24. {
  25. char ch=str.charAt(i);
  26. switch(ch)
  27. {
  28. case '(':st.push(t);flag=true;break;
  29. case ')':st.pop();flag=false;break;//考虑到某些点没有右孩子,故置false
  30. case ',':flag=false;break;
  31. default:
  32. t=new Node(ch);
  33. if(R==null) R=t;//特判无根节点的情况!!!
  34. else if(flag) st.peek().ls=t;
  35. else st.peek().rs=t;
  36. break;
  37. }
  38. }
  39. }
  40. public void Search(Node t)
  41. /*函数功能:得到答案序列
  42. 由于后序序列格式是LRN,所以题目所求的序列为NRL。
  43. 根据要求,我们先处理根结点,再处理右子树,最后处理左子树即可。*/
  44. {
  45. if(t==null) return;
  46. ans+=t.w+" ";
  47. Search(t.rs);Search(t.ls);
  48. }
  49. }
  50. public static void main(String[] args)
  51. {
  52. Scanner in=new Scanner(System.in);
  53. String str=in.nextLine();
  54. BTree T=new BTree(str);
  55. T.Search(T.R);
  56. System.out.println(T.ans);
  57. }
  58. }

T9(核心代码:函数)

本题代码为T9代码。核心代码为函数。
输入的是二叉树对应的括号序列。
ps:本题与上一题相比只多了一行代码QAQ

  1. import java.util.*;
  2. public class hw4_9
  3. {
  4. public static class Node
  5. {
  6. char w;
  7. Node ls,rs;
  8. public Node(){ls=rs=null;}
  9. public Node(char ww){w=ww;ls=rs=null;}
  10. }
  11. public static class BTree
  12. {
  13. Node R;
  14. String ans;
  15. public BTree(String str)//函数功能:初始化+根据输入的括号序列建树
  16. {
  17. R=null;
  18. ans="";
  19. Stack<Node> st=new Stack<>();
  20. Node t=null;
  21. int n=str.length();
  22. boolean flag=true;
  23. for(int i=0;i<n;i++)
  24. {
  25. char ch=str.charAt(i);
  26. switch(ch)
  27. {
  28. case '(':st.push(t);flag=true;break;
  29. case ')':st.pop();flag=false;break;
  30. case ',':flag=false;break;
  31. default:
  32. t=new Node(ch);
  33. if(R==null) R=t;
  34. else if(flag) st.peek().ls=t;
  35. else st.peek().rs=t;
  36. break;
  37. }
  38. }
  39. }
  40. public void Search(Node t)
  41. /*函数功能:得到答案序列
  42. 由于要求从右到左,我们先遍历右子树,再遍历左子树。
  43. 注意只把叶子结点加入输出结果即可。*/
  44. {
  45. if(t==null) return;
  46. if(t.ls==null&&t.rs==null) //唯一多出的一行
  47. ans+=t.w+" ";
  48. Search(t.rs);Search(t.ls);
  49. }
  50. }
  51. public static void main(String[] args)
  52. {
  53. Scanner in=new Scanner(System.in);
  54. String str=in.nextLine();
  55. BTree T=new BTree(str);
  56. T.Search(T.R);
  57. System.out.println(T.ans);
  58. }
  59. }

T10(核心代码:函数)

本题代码为T10代码。核心代码为函数。
输入的是二叉树对应的括号序列。

  1. import java.util.*;
  2. public class hw4_10
  3. {
  4. public static class BTree
  5. {
  6. char[] T=new char[1000];//用顺序结构存储二叉树(空间开大点以防数组越界)
  7. int ans;
  8. public BTree(String str)
  9. /*函数功能:初始化+根据括号序列用顺序结构存下树
  10. 这里连Stack都删了。因为对任意编号为i的点,双亲为(int)i/2,左二子为2i,右儿子为2i+1,结点跳转很方便,不需要用Stack来记忆双亲是谁。*/
  11. {
  12. ans=0;
  13. Arrays.fill(T,'#');//先把T所有元素初始化为#,这样就很容易判断是否越界、是否有儿子了
  14. int Now=1,n=str.length();
  15. for(int i=0;i<n;i++)
  16. {
  17. char ch=str.charAt(i);
  18. switch(ch)
  19. {
  20. case '(':Now*=2;break;//进左儿子
  21. case ')':Now/=2;break;//回到双亲结点
  22. case ',':Now++;break;//进右儿子
  23. default:T[Now]=ch;break;
  24. }
  25. }
  26. }
  27. public void Search(int t)
  28. /*函数功能:遍历全树统计答案
  29. 其实随便按哪个顺序遍历都行,这里用了先序遍历。
  30. 遇到双分支结点时统计答案即可。*/
  31. {
  32. if(T[t]=='#') return;//是#就代表越界
  33. if(T[t*2]!='#'&&T[t*2+1]!='#') ans++;//不是#就代表存在左/右儿子
  34. Search(t*2);Search(t*2+1);
  35. }
  36. }
  37. public static void main(String[] args)
  38. {
  39. Scanner in=new Scanner(System.in);
  40. String str=in.nextLine();
  41. BTree T=new BTree(str);
  42. T.Search(1);//顺序结构存储下,1(不是0!)为根节点
  43. System.out.println(T.ans);
  44. }
  45. }

T11(核心代码:函数)

本题代码为T11代码。核心代码为(对应第二小问)和(对应第三小问)函数。
第一行输入字符串。
第二行输入数组。

  1. //ps:以后不要开什么全局变量和全局函数,加static加到醉。。。把这些变量和函数都塞进一个static类中就没事了。
  2. import java.util.*;
  3. public class hw4_11
  4. {
  5. static final int N=1000;
  6. public static class Node
  7. {
  8. int ch,w;
  9. Node lc,rc;
  10. public Node(int chh,int ww){ch=chh;w=ww;lc=rc=null;}
  11. public int getw(){return w;}
  12. }
  13. public static class Tree//养成类名通通加static的好习惯
  14. {
  15. Node R;//哈夫曼树的根
  16. int n;
  17. String str;
  18. int[] w=new int[N];
  19. char[] path=new char[N];//存当前遍历点对应的哈夫曼编码
  20. String[] Code=new String[N];//存给定字符(叶子结点)对应的哈夫曼编码
  21. public Tree(String str1,int[] w1)
  22. //函数功能:初始化各变量+建哈夫曼树+用二叉链存储结构存树
  23. {
  24. str=str1;w=w1;n=str.length();
  25. PriorityQueue<Node> Q=new PriorityQueue<>((a,b)->a.w-b.w);//按每个字符的w值从小到大排序的优先队列
  26. for(int i=0;i<n;i++) Q.offer(new Node(i,w[i]));
  27. while(Q.size()>1)
  28. {
  29. Node p=Q.poll(),q=Q.poll();
  30. Node t=new Node(-1,p.w+q.w);
  31. t.lc=p;t.rc=q;
  32. Q.offer(t);
  33. }
  34. R=Q.poll();
  35. }
  36. public void getCode(Node t,int d)
  37. //函数功能:求得每个字符对应的哈夫曼编码
  38. {
  39. if(t==null) return;
  40. if(t.lc==null&&t.rc==null)//哈夫曼树中只有叶子结点才对应字符
  41. {
  42. Code[t.ch]="";//编码初始化为空串
  43. for(int i=1;i<=d;i++) Code[t.ch]+=path[i];
  44. }
  45. d++;
  46. path[d]='0';getCode(t.lc,d);
  47. path[d]='1';getCode(t.rc,d);
  48. }
  49. public void printCode()
  50. //函数功能:输出每个字符对应的哈夫曼编码
  51. {
  52. System.out.print("The answer of task (2):");
  53. for(int i=0;i<n;i++) System.out.print(str.charAt(i)+":"+Code[i]+" ");
  54. System.out.println();
  55. }
  56. public int calcWPL(Node t,int d)
  57. //函数功能:计算该哈夫曼树的带权路径长度
  58. {
  59. if(t==null) return 0;
  60. int sum=0;
  61. if(t.lc==null&&t.rc==null) sum=w[t.ch]*d;
  62. d++;
  63. return sum+calcWPL(t.lc,d)+calcWPL(t.rc,d);
  64. }
  65. }
  66. public static void main(String[] args)
  67. {
  68. Scanner in=new Scanner(System.in);
  69. String str=in.nextLine();
  70. int n=str.length();
  71. int[] w=new int[N];
  72. for(int i=0;i<n;i++) w[i]=in.nextInt();
  73. //实现第一小问的语句如下
  74. Tree T=new Tree(str,w);
  75. //实现第二小问的语句如下
  76. T.getCode(T.R,0);
  77. T.printCode();
  78. //实现第三小问的语句如下
  79. System.out.println("The answer of task (3):"+T.calcWPL(T.R,0));
  80. }
  81. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注