bool cmp(ID* obj1, ID* obj2){return obj1->id>obj2->id;}
bool cmp2(ID* obj1, ID* obj2){return obj1->id<=obj2->id;}
Сортировка vector'a слиянием
Image Processing, подогнал его под свой вектор, а в результате программа завершается аварийно.Исправьте, пожалуйста меня!
Эти функции определены в классе Programm
После вызова MergeSort(collection+n/2, n-n/2) программа вылетает с ошибкой Expression:(_Pvector == NULL || (((_Myvec *)_Pvector)->_Myfirst <= _Ptr && _Ptr <= ((_Myvec *)_Pvector)->_Mylast));
Нашел в инете алгоритм,
Эти функции определены в классе Programm
Код:
Код:
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;
}
}
}
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);
}
{
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));
Код:
MyCollection *collection;
n=100500;
*(collection+n/2)
n=100500;
*(collection+n/2)
Чтобы было проще - приведу пример:
Код:
void velocycleSort(std::vector<int>* vectorPtr);
void f()
{
std::vector<int> a[3]; // три массива
...
for ( vector<int>* curr = a; curr<a+3; curr++ )
velocycleSort(curr); // сортировка первого, потом второго и третьего массива
}
void f()
{
std::vector<int> a[3]; // три массива
...
for ( vector<int>* curr = a; curr<a+3; curr++ )
velocycleSort(curr); // сортировка первого, потом второго и третьего массива
}
Вот вы только скажите, зачем так сложно?
Сортировка не идеальная, пожертвовал качеством ради наглядности и простоты:
Код:
#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;
}
#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 предикат передается по-значению, не по ссылке? Этого момента я не понимаю...
Задали именно слиянием
Код:
#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;
}
#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;
}
писал на первом курсе, коряво, поменяешь стэк на вектор и будет тебе счастье.
Цитата: Artem_3A
Код:
...
Может, я ошибаюсь, но похоже, что у вас бага закралась) Я когда-то на таком тоже запоролся.[CODE]int* b = new int[size/2];
int* c = new int[size/2];
Может, я ошибаюсь, но похоже, что у вас бага закралась) Я когда-то на таком тоже запоролся.[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();
говорю же, писал на первом курсе, сохранилось это дело чудом, чего там писал уже помню смутно, так что сильно не пинайте за сроком давности. автору вообще посоветовал бы использовать вместо массивов вектора.
Цитата: Artem_3A
говорю же, писал на первом курсе, сохранилось это дело чудом, чего там писал уже помню смутно, так что сильно не пинайте за сроком давности. автору вообще посоветовал бы использовать вместо массивов вектора.
У меня итак вектор используется
Или ты о функции SortMerge2 говоришь?