Программирование на C - вставка сортируется в односвязном списке

Я почти закончил с моим назначением, последняя часть - написать функцию, которая сортирует односвязный список с помощью сортировки вставкой. Я также связан предопределенными структурами и typedefs моего назначения:

struct le {
    int value;
    struct le *next;
};

typedef struct le listenelement;
typedef listenelement *list;

Те, которые я не могу изменить. Функция сортировки вставок должна работать с этими параметрами. Если параметр m отрицателен, предполагается, что список отсортирован в порядке убывания, а в противном случае - в порядке возрастания.

void sort(int m, list *l);

РЕДАКТИРОВАТЬ:

Вот моя попытка реализовать ответы отсюда.. Я до сих пор не могу заставить его работать. Я попытался создать новый список, который является конечным результатом с именем "asc" (для отсортированного по возрастанию списка) и знакомым списком "aux", но я застрял...

void sort(int m, list *l){              
    if ((m == 0) || (*l == NULL)) {
        printf("Error.\n");
    } else {
        if (m>0) {
            listenelement head = {0,NULL};              
            list asc = {&head};
            list aux = *l;
            while (aux != NULL) {                       
                int val = aux->value;                                                   
                delete_elem(val,&aux);                                                  
                while ((asc->next != NULL) && ((asc->value)<val)) {         
                    printf("%d\n", (asc->value));                                       
                    asc=asc->next;
                }
                insert(val,&asc);   
                asc = &head;                            
            }
            *l = &head;
        }
    }
}

1 ответ

сортировка вставок не может работать в односвязном списке, не так ли? Вы можете только идти вперед в них.

Обычная реализация сортировки вставками для массивов не имеет точного аналога, который хорошо работает с односвязными списками, но это не означает, что алгоритм не может быть применен к таким спискам. Вам просто нужно более широкое понимание алгоритма, который Википедия характеризует как:

Сортировка вставки повторяется, потребляя один входной элемент за каждое повторение и увеличивая отсортированный список вывода. Каждая итерация, сортировка вставкой, удаляет один элемент из входных данных, находит его местоположение в отсортированном списке и вставляет его туда. Повторяется до тех пор, пока не останется никаких элементов ввода.

Обратите внимание, что эта характеристика не зависит от порядка, в котором вы можете проходить элементы. Вы застряли на обычной реализации шага вставки, который включает в себя итерацию назад по списку, чтобы найти позицию вставки. На самом деле вы могли бы сделать это с помощью своего односвязного списка, в смысле тестирования каждого предыдущего элемента от ближайшего к наиболее удаленному, но это изменило бы общую асимптотическую сложность алгоритма на O (N3). Нехорошо. И не обязательно.

Что плохого в нахождении позиции вставки путем итерации вперед по подсписку с самого начала? Это все еще удовлетворяет алгоритмическому определению (как дано Википедией), сохраняет асимптотическую сложность, и в общем случае оно получает столько же преимуществ от того, что исходный подсписок находится в отсортированном порядке, чем обычная реализация.

Главное, что отличается, это лучшие сценарии и сценарии. Наилучший случай для обычной реализации - это то, что элементы изначально расположены по порядку, а наихудший случай - то, что они изначально в обратном порядке. Они просто перевернуты для наивной реализации подхода итерации-вперед, но со связанным списком и тщательной реализацией эти два случая могут быть сделаны почти одинаково хорошими. Реализация с повторением в обратном направлении имеет некоторые дополнительные практические последствия для массивов, но они не применяются к связанным спискам.

Другие вопросы по тегам