#include <stdio.h>
#include <stdlib.h>
// Define the structure for a tree node.
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
// Function to create a new tree node.
struct TreeNode* createNode(int value) {
struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));
newNode->val = value;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
// Function to check if two trees are mirrors of each other.
int areMirrors(struct TreeNode* tree1, struct TreeNode* tree2) {
// If both nodes are NULL, they are mirrors.
if (tree1 == NULL && tree2 == NULL) return 1;
// If one of them is NULL, they are not mirrors.
if (tree1 == NULL || tree2 == NULL) return 0;
// Check if the values of the nodes are equal and if the left subtree of one tree
// is a mirror of the right subtree of the other tree and vice versa.
return (tree1->val == tree2->val) &&
areMirrors(tree1->left, tree2->right) &&
areMirrors(tree1->right, tree2->left);
}
// Function to check if a tree is symmetric.
int isSymmetric(struct TreeNode* root) {
// An empty tree is symmetric.
if (root == NULL) return 1;
// Check if the left and right subtrees are mirrors.
return areMirrors(root->left, root->right);
}
// Main function to test the code.
int main() {
// Create a symmetric tree.
struct TreeNode* root = createNode(1);
root->left = createNode(2);
root->right = createNode(2);
root->left->left = createNode(3);
root->left->right = createNode(4);
root->right->left = createNode(4);
root->right->right = createNode(3);
// Check if the tree is symmetric.
if (isSymmetric(root)) {
printf("The tree is symmetric.\n");
} else {
printf("The tree is not symmetric.\n");
}
// Free the allocated memory (optional but good practice).
free(root->left->left);
free(root->left->right);
free(root->right->left);
free(root->right->right);
free(root->left);
free(root->right);
free(root);
return 0;
}
Explanation
- TreeNode Structure: We define a
TreeNode
structure that holds a valueval
and pointers to the left and right children. - createNode Function: This function allocates memory for a new node and initializes it with a given value.
- areMirrors Function: This recursive function checks if two trees are mirror images of each other:
- If both nodes are
NULL
, return1
(true). - If one is
NULL
and the other isn’t, return0
(false). - Check if the node values are equal, and the left subtree of one is a mirror of the right subtree of the other.
- If both nodes are
- isSymmetric Function: This function checks if the entire tree is symmetric by calling
areMirrors
with the left and right children of the root. - Main Function: This creates a simple symmetric tree, checks its symmetry, and prints the result.
Output
When the program runs with the example tree, the output will be:
The tree is symmetric.
If you modify the tree structure in the main function (e.g., remove a node), it will print:
The tree is not symmetric.
Memory Management
In this example, memory is freed for each allocated node at the end. It’s a good practice, though the program will automatically free memory on termination in many cases. However, explicitly freeing memory is important in larger applications to prevent memory leaks.