一、编写算法判别给定二叉树是否为完全二叉树。
答:
判断一个树是不是完全二叉树,可以使用BFS算法进行实现。在层序遍历的时候,空结点一定位于最后面。如果中间存在空结点则表明不是完全二叉树。继续执行直至遍历完成。
该算法实现的伪代码如下:
/* 函数名称:判断树是不是完全二叉树 函数传入:树的根节点指针 函数返回值类型:bool型 是返回true不是返回false */ bool isCompleteTree(Tree *root) { QueueInit(&queue); //构建一个队列 if(root == NULL) { //空树也是完全二叉树 return true; } QueuePush(&queue, root -> data);//把根结点压入队列中 while(!(QueueEmpty(&queue))) { Tree *front = QueueFront(&queue); //取出队首结点 QueuePop(&queue); //弹出队首结点 if(front == NULL) { break; //该层有元素为空 } QueuePush(&queue, front -> left); QueuePush(&queue, front -> right); } while(!(QueueEmpty(&queue))) { Tree *front = QueueFront(&queue); //取出队首结点 QueuePop(&queue); //弹出队首结点 if(front != NULL) { return false; //如果还剩下元素代表不是完全二叉树 } } QueueDestory(&queue); //销毁队列 return true; } |
算法分析:该算法实现的时间复杂度为O(n+e)。是一种对树遍历的高效算法。空间多使用一个队列的空间。
二、对以孩子-兄弟链表表示的树编写计算树的深度的算法。
答:
对于该题我们可以用递归的算法进行实现。先将树拓展为森林,再将森林转换为二叉树。如果二叉树根存在,左子树深度加一与右子树深度最大值即为此状态下的深度。
该算法实现的伪代码如下:
/* 函数名称:求树的深度 函数传入参数:树根节点 返回值类型:int 树的深度 */ int getDepth(Tree *root) { if(root == NULL) return 0; else return max(1 + getDepth(root -> firstchild), getDepth(root -> nextsibling)); } |
算法分析:该算法用递归的方式进行实现,思路简洁,代码短小高效。这是解决该问题的较好方法。
三、假设以二叉链表存储的二叉树中,每个结点所含数据元素均为单字母,试编写算法,按树状打印二叉树的算法。
答:
观察图表可以知道,字母前面的空格与层数有关。空格个数为层数减一。打印的顺序为中序遍历的逆序列,我们可以通过递归的方法实现打印。
该算法实现的伪代码如下:
/* 函数名称:按要求打印二叉树 函数传入参数:根节点 与 层数 函数返回值类型:void */ void PrintAsTree(BiTree *root, int layer) { //i代表所在层次 if (root) { PrintAsTree(root -> rchild, layer + 1); //访问右子树 for (int j = 0; j < layer - 1; ++j) { printf(" "); } printf("%c ", root -> data); PrintAsTree(root -> lchild, i + 1); //访问左子树 } } |
算法分析:该算法是由递归实现遍历。由于发现其内在规律,使其代码更加简洁。这是解决该问题较好的算法。