Well, I think this is a good exercise for anyone learning C.
Yes, as other buddies mentioned, you may go with the 'partition then partial sort' approach.
But since 'pointer of function' is a key function of C,
you will face it sooner or later,
now it is a good point to take a glimpse to it.
When 'sorting', it important to define 'which one is greater'.
Like
#include  <stdio.h> 
#include  <string.h>
int normal_is_greater(int a, int b){
    return a > b;
}
void plain_buble(int arr[], int n)
{   // as the name says, this is a 'plain buble sort'
    int i,j;
    for (i=0; i< n; i++) {
        for (j = 0 ; j < (n-i-1); j++){
            if ( normal_is_greater(arr[j], arr[j+1]) )
            {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}
int special_is_greater(int a, int b){
    if (a>=0 && b <0)  {
        return 0;
    } else if ( a<0 && b >=0)  {
        return 1;
    } else if ( a<0 && b <0)  {
        return a < b;
    } 
    else
        return a > b;
}
void buble_using_special_comparer(int arr[], int n)
{   // copy-pasted from 'plain_buble', but substitute a single row.
    int i,j;
    for (i=0; i< n; i++) {
        for (j = 0 ; j < (n-i-1); j++){
            if (  special_is_greater(arr[j], arr[j+1]) )  // <== yes, here 
            {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}
int main() 
{ 
    int arr[] = {1 ,-1 ,-3 , -2, 7, 5, 11, 6 }; 
    int n = sizeof(arr)/sizeof(arr[0]); 
    plain_buble(arr,  n);
    for (int i = 0; i < n; i++) 
    {
        printf("%d ", arr[i]);
    }
    printf("\n"); 
    buble_using_special_comparer(arr,  n);
    for (int i = 0; i < n; i++) 
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
  
    return 0; 
} 
Result:
-3 -2 -1 1 5 6 7 11 
1 5 6 7 11 -1 -2 -3 
As long as we have a 'plain_buble' sort function,
we can modify a bit to turn it into 'the sort we want'.
But the above sample is still not cool,
because plain_buble and buble_using_special_comparer are almost the same.
We can use 'pointer of function' to do the magic.
Like:
#include  <stdio.h> 
#include  <string.h>
typedef int (* CompareFunc)(int a, int b);
void buble_sort(int arr[], int n, CompareFunc is_greater)
{   // as the name says, this is a 'plain buble sort'
    int i,j;
    for (i=0; i< n; i++) {
        for (j = 0 ; j < (n-i-1); j++){
            if (is_greater(arr[j], arr[j+1]) )
            {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}
int normal_is_greater(int a, int b){
    return a > b;
}
int special_is_greater(int a, int b){
    if (a>=0 && b <0)  {
        return 0;
    } else if ( a<0 && b >=0)  {
        return 1;
    } else if ( a<0 && b <0)  {
        return a < b;
    }
    else
        return a > b;
}
int main() 
{ 
    int arr[] = {1 ,-1 ,-3 , -2, 7, 5, 11, 6 }; 
    int n = sizeof(arr)/sizeof(arr[0]); 
    buble_sort(arr,  n,  normal_is_greater);
    for (int i = 0; i < n; i++) 
    {
        printf("%d ", arr[i]);
    }
    printf("\n"); 
    buble_sort(arr,  n, special_is_greater);
    for (int i = 0; i < n; i++) 
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
  
    return 0; 
}