Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Быстрая сортировка связного списка 
V
    Опции темы
Luyan
Дата 9.12.2009, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 180
Регистрация: 3.12.2008

Репутация: 2
Всего: 7



у меня есть односвязный список:
Код

struct Node
{
    int data;
    Node* next;
};

мне надо реализовать рекурсивную быструю сортировку. представляю себе это так:
Код

void quicksort(Node *head)
{
    if( ( head != NULL ) && ( head->next != NULL ) )
    {
        Node *pivot; // опорный элемент
        Node *left; // голова списка с элементами меньше pivot
        Node *right; // голова списка с элементами больше pivot 

        partition(head, pivot, left, right); // разделение

        quicksort(left);
        quicksort(right);
    }
}
// разделение
void partition(Node *head, Node *pivot, Node *left, Node *right)
{
    pivot = head; // опорный - первый элемент списка
    Node* Llink = left;
    Node* Rlink = right;
    head = head->next;
    while(head != NULL)
    {
        if( head->data < pivot->data )
        {
            // вставляю перед pivot
        }
        else
        {

        }
        head = head->next;
    }
}

допустим у меня есть текущий элемент списка, значение которого меньше опорного, следовательно, я должен вставить его в начало, когда я буду вставлять элемент перед опорным я выделю динамическую память,  скопирую значение текущего элемента в новый,  потом текущий элемент удалю и поставлю указатель Llink на новый элемент. Затем передам указатель на дальнейшее разбиение левого "списка". То есть мне надо будет сохранить значение опорного элемента, и левую половину списка разбивать до опорного? так будет очень долго, нельзя ли как-нибудь по другому реализовать? без вставки и удаления.

Это сообщение отредактировал(а) Luyan - 9.12.2009, 20:57
PM   Вверх
mes
Дата 9.12.2009, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Luyan @  9.12.2009,  19:56 Найти цитируемый пост)
когда я буду вставлять элемент перед опорным я выделю динамическую память,  скопирую значение текущего элемента в новый,  потом текущий элемент удалю и поставлю указатель Llink на новый элемент.

не проще ли будет просто  поменять data (тем более что int), не трогая в остальном Node ?





--------------------
PM MAIL WWW   Вверх
Luyan
Дата 10.12.2009, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 180
Регистрация: 3.12.2008

Репутация: 2
Всего: 7



вот список:  ( p - pivot, h - head)
5    8    10    4    13    2
^    ^
p    h

дошёл до 4

5    8    10    4    13    2
^                  ^
p                   h

поменял значения:

4    8    10    5    13    2
^                 ^
p                  h

дальше так: Llink = pivot; pivot = head; и через дополнительный указатель смешу head 
4    8    10    5    13    2
^                  ^    ^
L                   p    h

двигаюсь:
4    8    10    5    13    2
^                 ^            ^
L                  p             h

не получается. 10 и 13 уже не там.
4    8    10    2    13    5
^                  ^
L                   p

Добавлено через 5 минут и 39 секунд
кажеться я вас не так понял...

Это сообщение отредактировал(а) Luyan - 10.12.2009, 00:12
PM   Вверх
mes
Дата 10.12.2009, 00:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



имелось ввиду типа этого :
Код

 if (node->data < node->next->data) std::swap (node->data, node->next->data);

однако для Вашего типа сортировки не подходит.. так как нельзя вставить в середину, можно только поменять.
Но для вставки тоже совсем необязательно выделять дополнительно память- можно поменять лишь откорректировать указатели next.


Это сообщение отредактировал(а) mes - 10.12.2009, 00:25


--------------------
PM MAIL WWW   Вверх
Luyan
Дата 10.12.2009, 00:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 180
Регистрация: 3.12.2008

Репутация: 2
Всего: 7



Цитата(mes @  10.12.2009,  00:24 Найти цитируемый пост)
Но для вставки тоже совсем необязательно выделять дополнительно память- можно поменять лишь откорректировать указатели next.

 smile , можете объяснить как?
PM   Вверх
mes
Дата 10.12.2009, 01:27 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



вот псевдокодом, набросал не проверяя...

Код

//изъятие элемента
node * remove (node * prev, node * curr)// prev == Null для первого
{
     if (prev) prev->next = curr->next;
     if (curr) curr->next = NULL;
     return curr;
}
// корректировка расположения элементов в списке
// curr должен быть заранее изъят
void place (node * prev, node *curr, node * next)
{
   if (prev) prev->next = curr;
   if (curr)  curr->next = next;
}

void sort ()
{
//..
   node * to; // после которой произойдет вставка
   node * from; //  которая будет изъята
   node * prevfrom; // предыдыдущая от from , может быть NULL
//..
   place (to, remove(prevfrom, from), to->next);
//..
}


Это сообщение отредактировал(а) mes - 10.12.2009, 01:29


--------------------
PM MAIL WWW   Вверх
Luyan
Дата 11.12.2009, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 180
Регистрация: 3.12.2008

Репутация: 2
Всего: 7



Цитата(mes @  10.12.2009,  01:27 Найти цитируемый пост)
node * prevfrom; // предыдыдущая от from , может быть NULL

то есть сначала идёт prevfrom, потом from? to - после которого буду вставлять, для первого случая == head, после вставки его смещаю?
Код

Node *remove (Node *prev, Node *curr)// prev == Null для первого
{
     if (prev)
         prev->next = curr->next;
     if (curr)
         curr->next = NULL;
     return curr;
}
// корректировка расположения элементов в списке
// curr должен быть заранее изъят
void place(Node *prev, Node *curr, Node *next)
{
    if (prev)
        prev->next = curr;
    if (curr)
        curr->next = next;
}
void sort(Node* head)
{
    Node *to = head; // после которой произойдет вставка
    int pivot = head->data; // опорный элемент
    Node *from = head; // которая будет изъята
    Node *prevfrom = head; // предыдыдущая от from , может быть NULL
    from = from->next; // from = head->next;
    while(!from) // делаю проход по списку
    {
        if(from->data < pivot)
        {
            place(to, remove(prevfrom, from), to->next);
            to = to->next; // вставлять буду после слеующего
        }
        from = from->next;
        prevfrom = prevfrom->next;
    }
    //..
} 

ничего не происходит, что не так? может ввести указатель на указатель, допустим так, псевдокод:
Код

sort()
{
    Node ** to = &head; // это для первого случая

    //..
    // цикл прохода..
    if(from->data < pivot)
    {
        *to= head;
        to= &(head->next); // смещаю
        // так создам первую половину
    }
    else
    {
        //тут вторую
    }
    // конец прохода..
    // обнулю указатели *, в ** указателе будет лежать одна из половин 
}


Добавлено через 5 минут и 34 секунды
только как потом связать...

Это сообщение отредактировал(а) Luyan - 11.12.2009, 22:11
PM   Вверх
Luyan
Дата 12.12.2009, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 180
Регистрация: 3.12.2008

Репутация: 2
Всего: 7



удалось, реализовал своим способом. mes, спасибо за подкунутую идею  smile 

Это сообщение отредактировал(а) Luyan - 12.12.2009, 16:50
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0490 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.