前情回顾:
二叉树的遍历以及递归的分治思想: 传送门
本篇博客将接着上文继续带来一种遍历二叉树的方法 —— 层序遍历,并一起领略一下二叉树的OJ题,话不多说,准备启航!
所谓层序遍历就是按照层数,将二叉树一层一层的遍历。
层序遍历的结果为:A B C D E F
那么我们该如何实现层序遍历呢:
队列不熟悉的小伙伴点这里: 传送门
思想:
注意:
我们这里入队的不是结点的值,因为我们还要将结点的孩子带到队列中去,所以我们这里入队的是结点 或 结点的指针,很显然入结点的指针更好,因为它占用的空间很小。
这时候我们当时实现队列的时候对数据类型重命名的优势就显现出来了:
//二叉树的层序遍历
void LevelOrder(BTNode* root)
{
Queue q;
QueueInit(&q);
//根先进队列printf()
if (root)
{
QueuePush(&q, root);
}
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
printf("%d ", front->data);
if (front->left)
{
QueuePush(&q, front->left);
}
if (front->right)
{
QueuePush(&q, front->right);
}
}
printf("\n");
QueueDestroy(&q);
}
完全二叉树有个特性,它的前 k - 1 层是满二叉树,最后一层是连续的。
这里我们还是用到了刚刚层序遍历的思想,还是用到了队列这个结构。
思想:
//判断二叉树是否是完全二叉树
bool BTreeComplete(BTNode* root)
{
Queue q;
QueueInit(&q);
//根先进队列printf()
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)
{
QueueDestroy(&q);
return false;
}
}
//循环结束,说明全是空并且出完了
//此时就是完全二叉树
QueueDestroy(&q);
return true;
}
二叉树的题目中还有一类比较重要的题目,那就是二叉树的还原。
题目会给出二叉树的前序遍历和中序遍历,或者后序遍历和中序遍历,根据条件将二叉树还原出来。
看例题:
已知某二叉树的前序遍历序列为ABDEC,中序遍历序列为BDEAC,则该二叉树( )
A.是满二叉树
B.是完全二叉树,不是满二叉树
C.不是完全二叉树
D.是所有的结点都没有右子树的二叉树
根据二叉树各个遍历的特性:
前序遍历 : - (先根遍历):根节点,左子树,右子树
中序遍历 : 左子树, 根节点, 右子树
后序遍历 : - (后跟遍历): 左子树,右子树,根节点
层序遍历 : 一层一层遍历
下面来说一下这题的思路:
12.已知某二叉树的中序遍历序列为JGDHKBAELIMCF,后序遍历序列为JGKHDBLMIEFCA,则其前序遍历序列为()
A.ABDGHJKCEFILM
B.ABDGJHKCEILMF
C.ABDHKGJCEILMF
D.ABDGJHKCEIMLF
所以前序遍历为:A B D G J H K C E I L M F
故选 B
bool isUnivalTree(struct TreeNode* root)
{
if(root == NULL)
{
return true;
}
if(root->left && root->left->val != root->val)
{
return false;
}
if(root->right && root->right->val != root->val)
{
return false;
}
return isUnivalTree(root->left) && isUnivalTree(root->right);
}
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
if(p == NULL && q == NULL)
{
return true;
}
if(p == NULL || q == NULL)
{
return false;
}
if(p->val != q->val)
{
return false;
}
return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
bool _isSymmetric(struct TreeNode* p, struct TreeNode* q)
{
if(q == NULL && p == NULL)
{
return true;
}
if(q == NULL || p == NULL)
{
return false;
}
if(q->val != p->val)
{
return false;
}
return _isSymmetric(p->left, q->right) && _isSymmetric(p->right, q->left);
}
bool isSymmetric(struct TreeNode* root)
{
if(root == NULL)
{
return true;
}
return _isSymmetric(root->left, root->right);
}
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
if(p == NULL && q == NULL)
{
return true;
}
if(p == NULL || q == NULL)
{
return false;
}
if(p->val != q->val)
{
return false;
}
return isSameTree(p->left,q->left) && isSameTree(p->right, q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot)
{
if(root == NULL && subRoot == NULL)
{
return true;
}
if(root == NULL && subRoot != NULL)
{
return false;
}
return isSameTree(root,subRoot)
|| isSubtree(root->left,subRoot)
|| isSubtree(root->right,subRoot);
}
#include
#include
typedef struct TreeNode
{
struct TreeNode* left;
struct TreeNode* right;
char data;
}BTNode;
BTNode* CreatTree(char* arr, int* pi)
{
if(arr[*pi] == '#')
{
(*pi)++;
return NULL;
}
BTNode* root = (BTNode*)malloc(sizeof(BTNode));
root->data = arr[(*pi)++];
root->left = CreatTree(arr, pi);
root->right = CreatTree(arr, pi);
return root;
}
void InOrder(BTNode* root)
{
if(root == NULL)
{
return;
}
InOrder(root->left);
printf("%c ",root->data);
InOrder(root->right);
}
int main()
{
char arr[100];
memset(arr, 0, sizeof(char) * 100);
scanf("%s", arr);
int i = 0;
BTNode* root = CreatTree(arr, &i);
InOrder(root);
return 0;
}