210 likes | 391 Views
p.126 1. a. a 是根结点; dmnfjkl 是叶结点; c 是 g 的双亲; c,a 是 g 的祖先; j,k 是 g 的孩子; imn 是 e 的子孙; d 是 e 的兄弟; g,h 是 f 的兄弟; b 的层次是 2 ; n 的层次是 5 ; 树的深度是 5 ; 以 c 为根的子树深度是 3 ; 树的度数是 3. b. c. e. d. g. f. h. i. j. k. l. m. n. p. 126 2.
E N D
p.126 1 a a是根结点;dmnfjkl是叶结点;c是g的双亲; c,a是g的祖先; j,k是g的孩子; imn是e的子孙;d是e的兄弟;g,h是f的兄弟;b的层次是2;n的层次是5; 树的深度是5; 以c为根的子树深度是3; 树的度数是3. b c e d g f h i j k l m n
p. 126 2 一棵度为二的有序树与一棵二叉树的区别在于:有序树的结点次序是相对于另一结点而言的,如果有序树中的子树只有一个孩子时,这个孩子结点就无须区分其左右次序,而二叉树无论其孩子数是否为2,均需确定其左右次序,也就是说二叉树的结点次序不是相对于另一结点而言而是确定的。
p.126 3 三个结点的树只有两种形态
p. 126 4 设该树中的叶子数为n0个。该树中的总结点数为n个,则有: n=n0+n1+n2+…+nm (1) 又有除根结点外,树中其他结点都有双亲结点,且是唯一的(由树中的分支表示),所以,有双亲的结点数为: n-1=0*n0+1*n1+2*n2+…+m*nm (2) 联立(1)(2)方程组可得: 叶子数为: n0=1+0*n1+1*n2+2*n3+...+(m-1)*nm
p.126 5 (1) 层号为h的结点数目为kh-1 (2) 编号为 i 的结点的双亲结点的编号是: (i-2)/k+1 (/表示整除)。 (3) 编号为 i 的结点的第 j 个孩子结点编号是:k*(i-1)+1+j; (4) 编号为i的结点有右兄弟的条件是(i-1)能被k整除 右兄弟的编号是i+1.
p. 126 6 高度为h的完全二叉树至少有2h-1个结点,至多有2h-1个结点(也就是满二叉树)。 空树高度为0。
p. 126 7 n 个结点的K叉树共有n*k个指针域,已使用的指针域为n-1,所以空指针的个数为: n(k-1)+1;
1 p. 126 8 3 12 12 12 7 7 3 7 1 3 12 1 3 7 1
p. 126 9 (1) 前序序列和中序序列相同的二叉树是:空二叉树或没有左子树的二叉树(右单支树)。 (2) 中序序列和后序序列相同的二叉树是:空二叉树或没有右子树的二叉树(左单支树)。 (3) 前序序列和后序序列相同的二叉树是:空二叉树或只有根的二叉树。 (4) 前序、中序、后序序列均相同的二叉树:空树或只有根结点的二叉树。
p. 127 11 (a) 前序序列:12345 中序序列:24531 后序序列:54321 (b) 前序序列:12345 中序序列:13542 后序序列:54321 (c) 前序序列:12357864 中序序列:17583524 后序序列:78563421 (d) 前序序列:124735689 中序序列:742153896 后序序列:742589631
p. 128 22 (1) 求结点数的递归定义为: 若为空树,结点数为0 若只有根结点,则结点数为1;否则,结点数为根结点的左子树结点数+右子树结点数+1 (2) 求叶子数的递归定义为: 若为空树,叶子数为0 若只有根结点,则叶子数为1;否则,叶子数为根结点的左子树叶子数+右子树叶子数
typedef char DataType; //定义DataType类型 typedef struct node{ DataType data; struct node *lchild, *rchild; //左右孩子子树 }BinTNode; //结点类型 int Node(BinTNode *t) { //算结点数 if(t==NULL) return 0; if((t->lchild==NULL)&&(t->rchild==NULL)) return 1; return Node(t->lchild)+Node(t->rchild)+1; }
int Leaf(BinTNode *t) { //算叶子数 if(t) return 0; if ((t>lchild==NULL)&&(t->rchild==NULL)) return 1; return Leaf(t->lchild)+Leaf(t->rchild); }
p. 128 23 (1) 根据递归定义:二叉树的高度为: 当为空树时,高度为0; 当只有一个结点时,高度为1; 其他情况:高度为max(根的左子树高度,根的右子树高度)+1
int Height(BinTNode *t) {int hl, hr; if(t==NULL) return 0; if(t->lchild==NULL)&&(t->rchild==NULL) return 1; hl=Height(t->lchild); //根的左子树高度 hr=Height(t->rchild); //根的右子树高度 if (hl>=hr) return hl+1; else return h2+1; }
要求二叉树的宽度的话,则可根据树的高度设置一个数组temp。temp[i]用于存放第i层上的结点数(即宽度)。要求二叉树的宽度的话,则可根据树的高度设置一个数组temp。temp[i]用于存放第i层上的结点数(即宽度)。 在访问结点时,把相应计算该结点下一层的孩子数并存入相应数组元素中,遍历左子树后向上返回一层计算右子树的宽度,并取出最大的一个数组元素作为树的宽度。
#define M 10 //假设二叉树最多的层数 int Width(BinTNode *t) {int static n[M], i=1, max=0; if(t) { if(i==1) { //若是访问根结点 n[i]++; //第1层加1 i++; //到第2层 if(t->lchild) n[i]++; //若有左孩子则该层加1 if(t->rchild) n[i]++; } //若有右孩子则该层加1 else{ //访问子树结点 i++; //下一层结点数 if(t->lchild) n[i]++; if(t->rchild) n[i]++; } if(max<n[i]) max=n[i]; //取出最大值 Width(t->lchild); //遍历左子树 i--; //往上退一层 Width(t->rchild); } //遍历右子树 return max;}//算法结束
p. 128 24 要交换各结点的左右子树,最方便的办法是用后序遍历算法,每访问一个结点时把两棵子树的指针进行交换,最后一次访问是交换根结点的子树。 void ChangeBinTree(BinTNode **pt) { //交换子树 if(*pt) { //以指针为参数使得交换在实参的结点上进行 BinTNode *temp; ChangeBinTree(&(*pt)->lchild); ChangeBinTree(&(*pt)->rchild); temp=(*pt)->lchild; (*pt)->lchild=(*pt)->rchild; (*pt)->rchild=temp; } }