Ho eliminato quel'if perché in fondo non mi sembrava fondamentale, almeno per adesso..

Ho compilato ed eseguito questo codice, ma al momento di cancellare mi da un errore:
Errore di segmentazione.

Ho controllato allora meglio il codice, ma non sono riuscito a trovare l'errore.. dove sbaglio?

codice:
#include <stdio.h>
#include <stdlib.h>
// #include <malloc.h>

typedef struct nodo{
    int dato;
    struct nodo *ptrsx;
    struct nodo *ptrdx;
}nodo;

nodo* creazione(){
    nodo *q;
    q = malloc(sizeof(nodo));
    
    printf("\nInserisci un numero intero:\t");
    scanf("%i", &q->dato);
    printf("\n");
    
    q->ptrsx = NULL;
    q->ptrdx = NULL;
    
    return q;
}

void ins_ord(nodo *p,nodo *q) {
    nodo *r;
    r = p;
    
    if(r->dato > q->dato) {
        if(r->ptrsx == NULL) {
            r->ptrsx = q;
        }else {
            ins_ord(r->ptrsx,q);
        }
    } else {
        if(r->ptrdx == NULL) {
            r->ptrdx = q;
        } else {
            ins_ord(r->ptrdx, q);
        }
    }
}

nodo* ins_bin(nodo *p) {
    nodo *q;
    q = creazione();
    
    if(p == NULL) {
        return q;
    } else {
        ins_ord(p, q);
    }
    
    return p;
}

void visita(nodo *p){
    nodo *r;
    r = p;
    
    if(r->ptrsx != NULL) {
        visita(r->ptrsx);
    }
    
    printf("%i", r->dato);
    printf("\t");
    
    if(r->ptrdx != NULL) {
        visita(r->ptrdx);
    }
}

nodo* eliminazione(nodo *p, int val) {
    // if(p->dato == val)
        // p->dato = p->ptrsx;
    if(p == NULL)
        return NULL;
    else
        elimina(p->ptrsx);
}

int elimina(nodo *p) {
    int num;
    
    if(p->ptrsx == NULL) {
        num = p->dato;
        free(p);
        return num;
    } else if(p->ptrsx != NULL)
        elimina(p->ptrdx);
}

int main() {
    nodo *radice = NULL;
    
    int scelta = 1, num;
    radice = NULL;
    
    while(scelta != 0) {
        printf("1 - Inserimento ordinato;\n2 - Visita albero;\n3 - Cancella elemento;\n0 - Esci;\n\nScelta:\t");
        scanf("%i", &scelta);
        
        switch(scelta) {
            case 1: {
                radice=ins_bin(radice);
                
                break;
            }
            case 2: {
                printf("\nAlbero:\n");
                visita(radice);
                printf("\n\n");
                
                break;
            }
            case 3: {
                if(radice != NULL){
                    printf("\nInserisci il numero da cancellare:\t");
                    scanf("%d", &num);
                    
                    eliminazione(radice, num);
                } else {
                    printf("\nLa lista e' vuota.\n");
                }
                
                break;
            }
        }
    }
}