Как очистить память занятую древовидной структурой?

После выполнения программы на Си, как очистить память занятую древовидной структурой?

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <malloc.h>
#include <Windows.h>
#include<stdbool.h>
#include <locale.h>


struct node {
    int data;
    struct node* left;
    struct node* right;
};
void postorder(struct node* root) {
    if (root == NULL) return;
    postorder(root->left);
    postorder(root->right);
    printf("%d ->", root->data);
}
bool empty_tree(struct node* root)
{
    if (root = NULL) return true;
    else return false;
}

struct node* createNode(value) {
    struct node* newNode = malloc(sizeof(struct node));
    newNode->data = value;
    newNode->left = NULL;
    newNode->right = NULL;

    return newNode;
}

struct node* insertLeft(struct node* root, int value) {
    root->left = createNode(value);
    return root->left;
}


struct node* insertRight(struct node* root, int value) {
    root->right = createNode(value);
    return root->right;
}


int main() {
    struct node* root = createNode(1);
    insertLeft(root, 12);
    insertRight(root, 9);

    insertLeft(root->left, 5);
    insertRight(root->left, 6);
    printf("\nPostorder traversal \n");
    postorder(root);
}

Ответы (2 шт):

Автор решения: KoVadim

Очистка дерева делается классически рекурсивно. Где то так

void destroy(struct node* n)
{
  if (n == NULL) return; // если пусто - убегаем
  destroy(n->left);  // почистим левую часть
  destroy(n->right); // почистим правую часть
  free(n);           // ну и саму ноду
}
→ Ссылка
Автор решения: EOF

Примерно так:

void delete_tree(struct node* root)
{
    if (root)
    {
        delete_tree(root->left);
        delete_tree(root->right);
        free(root);
    }
}

PS: Какой смысл дерева, если можно помещать любое значение в любую ветку?

→ Ссылка