7. 二叉树查找值为x的节点
按照前序遍历的思想去实现,因为左边如果找到了,没必要再去右面找,此外,对于查找,与上述代码的思想类似,即看成两层,将其改成递归:
BTNode* TreeFind(BTNode* root, BTDataType x) { if (root == NULL) return NULL; if (root->data == x) return root; if (TreeFind(root->left, x)) return TreeFind(root->left, x); if (TreeFind(root->right, x)) return TreeFind(root->right, x); return NULL; }
当然也可以设置一个临时变量:
BTNode* TreeFind(BTNode* root, BTDataType x) { if (root == NULL) return NULL; if (root->data == x) return root; BTNode* lret = TreeFind(root->left, x); if (lret) return lret; BTNode* rret = TreeFind(root->right, x); if (rret) return rret; return NULL; }
8. 求二叉树的最大深度
为了突出最大深度,这里让其创建节点的时候2多加一个节点,即如下图:
仍然按照文章中突出的思想,看成两层,比较其长度,返回大的那个
int TreeHeight(BTNode* root) { if (root == NULL) return 0; if (root->left == NULL && root->right == NULL) return 1; return TreeHeight(root->left) + 1 > TreeHeight(root->right) + 1 ? TreeHeight(root->left) + 1 : TreeHeight(root->right) + 1; }
为了不让后面的长度过长影响美观,可以这样:
//求最大深度 int TreeHeight(BTNode* root) { if (root == NULL) return 0; int lefthight = TreeHeight(root->left); int righthight = TreeHeight(root->right); return lefthight > righthight ? lefthight + 1 : righthight + 1; }
9. 判断二叉树是否是完全二叉树
对于此图,不是一个二叉树,那么如何判断呢这个不为二叉树呢?
当我们把此二叉树的节点一一罗列(指针不为空的以其指向的data代替)
按照前序遍历:(将最后一层的左右孩子也包括在内)
1->2->4->3->NULL->5->6->NULL->NULL->NULL->NULL->NULL->NULL
那完全二叉树又是怎样罗列的呢?下面给个完全二叉树的图同样按照前序遍历来看看:
1->2->4->3->6->NULL->NULL->NULL->NULL->NULL->NULL
这时候我们会发现,完全二叉树的罗列过程中,只要出现了第一个空,后面就全为空,对于非完全二叉树,出现了第一个空之后,后面也会出现非空的节点,因此,二者的区别我们就看出来了,对于这种问题,仍然需要以队列的方向去考虑,即如层序遍历一样,先Push一个,当Pop掉时,让其将两个孩子拽到队列里面来,唯一区别就是节点为空也要拽入,上面的层序遍历已经提到,队列的data储存的是节点指针,即便为空,也能储存。
代码:
//判断二叉树是否是完全二叉树 int BinaryTreeComplete(BTNode* root) { Queue q; QueueInit(&q); if (root) QueuePush(&q, root); while (!QueueEmpty(&q)) { BTNode* front = QueueFront(&q); QueuePop(&q); if (front == NULL) { break; } QueuePush(&q, front->left); QueuePush(&q, front->right); } while (!QueueEmpty(&q)) { BTNode* front = QueueFront(&q); QueuePop(&q); if (front != NULL) { QueueDestory(&q); return false; } } QueueDestory(&q); return true; }
10. 销毁二叉树
销毁二叉树经过上面的各种描述应该很容易理解了
//销毁树 思路:找到左右子树之后再销毁本身,否则找不到子树 void BinaryTreeDestroy(BTNode* root) { if (root == NULL) { return; } BinaryTreeDestroy(root->left); BinaryTreeDestroy(root->right); free(root); }
11. 由二叉树的遍历序列构造二叉树
12. 总结
本文章所讲的二叉树仅仅是入门的二叉树,但相比之前学的,这里的递归二叉树仍是大家面对的一个前所未有的难点,但是只要记住这里的化繁为简,由简到繁的思想,碰到层数多的二叉树,就想象成两层去做,这样才能把握住其中的奥妙,而二叉树的oj题,我打算单独写成一篇,目的就是让大家先掌握这些基本的函数再去训练,否则效果不会很明显,让我们一起攻克难关,拿捏二叉树!