Four traversal methods of binary tree and necessary interview questions
Article directory
- Four traversal methods of binary tree and necessary interview questions
- foreword
- 1. Build a binary tree
- Two, four traversal methods
- Three or four traversal related interview questions
- 1. The first question: 144. Preorder traversal of binary tree
- 2. Question 2: 94. Inorder traversal of a binary tree
- 3. Question 3: 145. Post-order traversal of binary trees
- 4. Question 4: Determine whether a binary tree is a complete binary tree
- 5. Fifth question: KY11 binary tree traversal
- Finally: destroy the binary tree
- Summarize
foreword
This article introduces the pre-order traversal, middle-order traversal, post-order traversal, layer-order traversal and explanations of their related interview OJ questions !
1. Build a binary tree
Build the binary tree as shown in the figure. I won’t introduce too much here. If you want to know how to build it, you can refer to the previous blog!
The code is as follows (example):
typedef char BTDataType;
typedef struct BinaryTreeNode
{
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
BTDataType data;
}BTNode;
BTNode* BuyNode(BTDataType x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
if (node == NULL)
{
printf("malloc fail\n");
exit(-1);
}
node->data = x;
node->left = node->right = NULL;
return node;
}
BTNode* CreatBinaryTree()
{
BTNode* nodeA = BuyNode('A');
BTNode* nodeB = BuyNode('B');
BTNode* nodeC = BuyNode('C');
BTNode* nodeD = BuyNode('D');
BTNode* nodeE = BuyNode('E');
BTNode* nodeF = BuyNode('F');
nodeA->left = nodeB;
nodeA->right = nodeC;
nodeB->left = nodeD;
nodeC->left = nodeE;
nodeC->right = nodeF;
return nodeA;
}
Two, four traversal methods
1. Preorder traversal
The order of pre-order traversal is root —> left subtree —> right subtree . Let me introduce a simple method for you
The code is as follows (example):
// 二叉树前序遍历
void PreOrder(BTNode* root)
{
if (root == NULL) {
printf("NULL ");
return;
}
printf("%c ", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
2. Inorder traversal
The order of inorder traversal is left subtree -> root -> right subtree .
The code is as follows (example):
// 二叉树中序遍历
void InOrder(BTNode* root)
{
if (root == NULL) {
printf("NULL ");
return;
}
InOrder(root->left);
printf("%C ", root->data);
InOrder(root->right);
}
3. Post-order traversal
The order of post-order traversal is left subtree -> right subtree -> root .
The code is as follows (example):
// 二叉树后序遍历
void PostOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%C ", root->data);
}
Additional: Comparison chart of the first three traversals
4. Layer order traversal
Layer sequence traversal is to traverse layer by layer, as shown in the picture below + source code!
Here we use queues to implement layer order traversal, as shown in the figure below! Since there will be a lot of queue knowledge here, you can refer to: queue implementation
The code is as follows (example):
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root)
{
if (root == NULL)
return;
Queue q;
QueueInit(&q);
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
printf("%c ", front->data);
// 孩子带进队列
if (front->left)
QueuePush(&q, front->left);
if (front->right)
QueuePush(&q, front->right);
}
printf("\n");
QueueDestroy(&q);
}
Three or four traversal related interview questions
1. The first question: 144. Preorder traversal of binary tree
(1) Topic
The topics are as follows (example):
int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
}
(2) Ideas
Note here: the return value of this question is int* , that is, an array should be returned, and *returnSize is the size of the array elements 1. The size needs to be calculated by yourself. You can use the TreeSize
you wrote before. If you don’t know much, you can refer to: binary tree node Number 2. Use 1 sub-function to write the three steps of preorder traversal 3. When recursing, pay attention to passing the address of i, because when passing parameters, the formal parameter is a temporary copy of the actual parameter, and you need to pass &i 4. Finally, give the size to *returnSize to ensure the size of the array!
(3) Source code
The code is as follows (example):
//先求下数组的大小,便于开辟空间
int Treesize(struct TreeNode* root)
{
return root == NULL ? 0 : Treesize(root->left) + Treesize(root->right) + 1 ;
}
void _preorderTraversal(struct TreeNode* root , int* a, int* pi)
{
if(root == NULL)
{
return;
}
a[(*pi)++] = root->val;
_preorderTraversal(root -> left ,a,pi);
_preorderTraversal(root->right , a ,pi);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
int size = Treesize(root);
int* a = (int*)malloc(sizeof(int)*size);
int i = 0;
_preorderTraversal(root , a , &i);
*returnSize = size;
return a;
}
2. Question 2: 94. Inorder traversal of a binary tree
3. Question 3: 145. Post-order traversal of binary trees
The second and third questions have the same solution as the first question, so I won’t introduce too much here, and here are the answers directly!
The answer to the second question: as follows (example):
int Treesize(struct TreeNode* root)
{
return root == NULL ? 0 : Treesize(root->left) + Treesize(root->right) + 1 ;
}
void _inorderTraversal(struct TreeNode* root , int* a, int* pi)
{
if(root == NULL)
{
return;
}
_inorderTraversal(root -> left ,a,pi);
a[(*pi)++] = root->val;
_inorderTraversal(root->right , a ,pi);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize)
{
int size = Treesize(root);
int* a = (int*)malloc(sizeof(int)*size);
int i = 0;
_inorderTraversal(root , a , &i);
*returnSize = size;
return a;
}
The answer to the third question: as follows (example):
int Treesize(struct TreeNode* root)
{
return root == NULL ? 0 : Treesize(root->left) + Treesize(root->right) + 1 ;
}
void _postorderTraversal(struct TreeNode* root , int* a, int* pi)
{
if(root == NULL)
{
return;
}
_postorderTraversal(root -> left ,a,pi);
_postorderTraversal(root->right , a ,pi);
a[(*pi)++] = root->val;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize)
{
int size = Treesize(root);
int* a = (int*)malloc(sizeof(int)*size);
int i = 0;
_postorderTraversal(root , a , &i);
*returnSize = size;
return a;
}
4. Question 4: Determine whether a binary tree is a complete binary tree
(1) Ideas
(2) Source code
The code is as follows (example):
// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root)
{
Queue q;
QueueInit(&q);
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front == NULL)
{
break;
}
else
{
QueuePush(&q, front->left);
QueuePush(&q, front->right);
}
}
// 遇到空了以后,检查队列中剩下的节点
// 1、剩下全是空给,则是完全二叉树
// 2、剩下存在非空,则不是完全二叉树
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front)
{
QueueDestroy(&q);
return false;
}
}
QueueDestroy(&q);
return true;
}
5. Fifth question: KY11 binary tree traversal
(1) Topic
(2) Ideas
This question needs to be divided into different modules to complete!
1. Build a tree, use the structure TreeNode
2. Write in-order traversal , if you don’t know how to write, read the previous article!
3. If it is #, skip and return NULL, as shown in the figure below !
After building the binary tree, you can perform in-order traversal and print each node. If you don’t know about in-order traversal, you can refer to the previous section!
(3) Source code
The code is as follows (example):
#include<stdio.h>
#include <stdlib.h>
struct TreeNode {
struct TreeNode* left;
struct TreeNode* right;
char val;
};
struct TreeNode* CreateTree(char* str, int* pi) {
if (str[*pi] == '#') {
(*pi)++;
return NULL;
}
struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
root -> val = str[(*pi)++];
root -> left = CreateTree(str, pi);
root -> right = CreateTree(str, pi);
return root;
}
void InOrder(struct TreeNode* root) {
if (root == NULL)
return;
InOrder(root->left);
printf("%c ", root->val);
InOrder(root->right);
}
int main() {
char str[100];
while ((scanf("%s", str) != EOF)) {
int i = 0;
struct TreeNode* root = CreateTree(str, &i);
InOrder(root);
}
return 0;
}
Finally: destroy the binary tree
After we create the binary tree every time, we must destroy the binary tree, otherwise it will cause a memory leak !
(1) Source code
The code is as follows (example):
void BinaryTreeDestory(BTNode* root)
{
if (root == NULL)
{
return;
}
BinaryTreeDestory(root->left);
BinaryTreeDestory(root->right);
free(root);
}
(2) Recursive diagram
Want to destroy the binary tree shown in the picture! For the sake of convenience, I only drew the destruction recursion diagram on one path, and those who are interested can draw all of them!
Summarize
The above is what I will talk about today. This article introduces the four traversal methods of binary trees and the necessary interview questions.
If my blog is helpful to you, remember to support it three times, thank you for your support!