Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Сортировка vector'a слиянием

44K
13 мая 2010 года
m9yt
25 / / 27.02.2010
Нашел в инете алгоритм,Image Processing, подогнал его под свой вектор, а в результате программа завершается аварийно.Исправьте, пожалуйста меня!

Эти функции определены в классе Programm
 
Код:
bool cmp(ID* obj1, ID* obj2){return obj1->id>obj2->id;}
bool cmp2(ID* obj1, ID* obj2){return obj1->id<=obj2->id;}


Код:
void Programm::Merge(MyCollection *A, int nA,
                            MyCollection * B, int nB,
                             MyCollection * C)
{
    int a(0), b(0);
    while( a+b < nA+nB )
    {
        if( (b>=nB) || ( (a<nA) && cmp2(A->at(a),B->at(b))))
        {
            C->at(a+b) = A->at(a);
            ++a;
        } else {
            C->at(a+b) = B->at(b);
            ++b;
        }
    }
}


Код:
void Programm::MergeSort(MyCollection *collection , int n)//n=collection->size()
{
    ID* t;//указатель на абстр класс
    int i=0;
    if( n < 2 ) return;
    if( n == 2 )
    {          

        if(cmp(collection->at(0),collection->at(1)))
        {
            t=collection->at(0); collection->at(0)=collection->at(1); collection->at(1)=t;
        }
        return;
    }
    MergeSort(collection, n/2  );
    MergeSort(collection+n/2, n-n/2);
    MyCollection *B;
    B=new MyCollection;
    Merge(collection,n/2, collection+n/2,n-n/2, B);
    for(int i(0); i<n; ++i) collection->at(i)=B->at(i);
}

После вызова MergeSort(collection+n/2, n-n/2) программа вылетает с ошибкой Expression:(_Pvector == NULL || (((_Myvec *)_Pvector)->_Myfirst <= _Ptr && _Ptr <= ((_Myvec *)_Pvector)->_Mylast));
602
14 мая 2010 года
KPI Student
265 / / 16.12.2006
 
Код:
MyCollection *collection;
n=100500;
*(collection+n/2)
И чего мы сдеали? Мы обратились к массиву номер 50250 )

Чтобы было проще - приведу пример:
 
Код:
void velocycleSort(std::vector<int>* vectorPtr);

void f()
{
    std::vector<int> a[3]; // три массива
    ...
    for ( vector<int>* curr = a; curr<a+3; curr++ )
        velocycleSort(curr);  // сортировка первого, потом второго и третьего массива
}


Вот вы только скажите, зачем так сложно?
602
14 мая 2010 года
KPI Student
265 / / 16.12.2006
Вы уж простите, вспоминать сортировку слиянием ночью неохота, но вот вам, согласитесь, куда более гибкий и короткий пример пузырьковой. При желании, его легко доработать и до слияния.

Сортировка не идеальная, пожертвовал качеством ради наглядности и простоты:
Код:
#include <iostream>
#include <utility>
#include <vector>
#include <list>
#include <cassert>

template<class T>
void swap(T& a, T& b) { T tmp = a; a=b; b=tmp; }


template<class Container, class Predicate>
void sort(Container& container, Predicate& needSwap)
{
    Container::iterator begin = container.begin();
    Container::iterator end   = container.end();

    for (Container::iterator i=begin; i!=end; i++)
        for (Container::iterator j=begin; j!=end; j++)
            if ( needSwap(*i, *j) )
                swap(*i, *j);    
}

template<class Container>
void sort(Container& container)
{
    sort<Container>(container, std::less<Container::value_type>() );
}


int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<int> a;
    a.push_back(5);  a.push_back(2);   a.push_back(1);

    sort(a);
    assert( a[0]==1 && a[1]==2 && a[2]==5 );

    sort< std::vector<int> >(a, std::greater<int>());
    assert( a[0]==5 && a[1]==2 && a[2]==1 );

    std::list<double> d( a.begin(), a.end() );
    sort(d);
    assert( *d.begin()==1  &&  *a.begin()==5 );

    std::cout << "Ok" << std::endl;
    std::cin.get();    

    return 0;
}


ЗЫ. А кто-нибудь знает, из каких побуждений в STL предикат передается по-значению, не по ссылке? Этого момента я не понимаю...
44K
14 мая 2010 года
m9yt
25 / / 27.02.2010
Задали именно слиянием
307
14 мая 2010 года
Artem_3A
863 / / 11.04.2008
Код:
#include "stdafx.h"
#include <iostream>
#include <time.h>
#include <stack>

using std::cout;
using std::endl;
using std::stack;

void sortMerge1(stack<int>& a, int sizeA)
{
    stack<int> b, c;
    for(int i=1; i<(sizeA/2-2); i++)
    {
        b.push(a.top());
        a.pop();
        while(!a.empty())
        {
            if(a.top()>b.top())
                c.push(a.top());
            else
                b.push(a.top());
            a.pop();
        }
        while(!b.empty() && !c.empty())
        {
            if(b.top()<c.top())
            {
                a.push(b.top());
                b.pop();
            }
            else
            {
                a.push(c.top());
                c.pop();
            }
        }
        while(!b.empty())
        {
            a.push(b.top());
            b.pop();
        }
        while(!c.empty())
        {
            a.push(c.top());
            c.pop();
        }
    }
    while(!a.empty())
    {
        cout << a.top() << endl;
        a.pop();
    }
}

void sortMerge2(int* a, int size)
{
    if(size/2 < 1)
        return;
    int* b = new int[size/2];
    int* c = new int[size/2];
    int j = 0;
    for(int i=0;i<size;i+=2)
    {
        if(a<a[i+1])
        {
            b[j] = a;
            c[j] = a[i+1];
        }
        else
        {
            c[j] = a;
            b[j] = a[i+1];
        }
        j++;
    }
    sortMerge2(b, size/2);
    sortMerge2(c, size/2);
    j = 0;
    int k = 0;
    int i = 0;
    while(j<size/2 && k<size/2 && i<size)
    {
        if(b[j]<c[k])
        {
            a = b[j];
            j++;
        }
        else
        {
            a = c[k];
            k++;
        }
        i++;
    }
   
    while(j!=size/2)
    {
        a = b[j];
        i++;
        j++;
    }
    while(k!=size/2)
    {
        a = c[k];
        i++;
        k++;
    }
    delete [] b;
    delete [] c;
}

int _tmain(int argc, _TCHAR* argv[])
{
    stack<int> a1;
    const int sizeA = 16;
    int* a2 = new int[sizeA];
    srand(time(0));
    for(int i=0; i<sizeA; i++)
    {
        a1.push(a2=rand()%100);
    }
    sortMerge1(a1, sizeA);
    cout << "*********************"<<endl;
    sortMerge2(a2, sizeA);
    for(int i=0; i<sizeA; i++)
        cout << a2<< endl;
    cout << "*********************"<<endl;
    system("pause");
    return EXIT_SUCCESS;
}


писал на первом курсе, коряво, поменяешь стэк на вектор и будет тебе счастье.
602
15 мая 2010 года
KPI Student
265 / / 16.12.2006
Цитата: Artem_3A
 
Код:
...
Может, я ошибаюсь, но похоже, что у вас бага закралась) Я когда-то на таком тоже запоролся.[CODE]int* b = new int[size/2];
int* c = new int[size/2];
Насколько я понимаю, это будут две половинки исходного массива?

Тогда при исходном массиве размером в три элемента будут созданы две половинки по одному элементу. И один будет потерян.

UPD: Так как в коде этих сайз/2 много, то могу предложить при нечетном размере массива добавлять в него push_pack(INT_MAX) и запоминать в bool isAlignementUsed факт этого добавления.
Потом, соответственно, делать
if ( isAlignementUsed ) pop_back();
307
15 мая 2010 года
Artem_3A
863 / / 11.04.2008
говорю же, писал на первом курсе, сохранилось это дело чудом, чего там писал уже помню смутно, так что сильно не пинайте за сроком давности. автору вообще посоветовал бы использовать вместо массивов вектора.
44K
17 мая 2010 года
m9yt
25 / / 27.02.2010
Цитата: Artem_3A
говорю же, писал на первом курсе, сохранилось это дело чудом, чего там писал уже помню смутно, так что сильно не пинайте за сроком давности. автору вообще посоветовал бы использовать вместо массивов вектора.



У меня итак вектор используется
Или ты о функции SortMerge2 говоришь?

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог