From 94a06d8cae4e216207281d15e6d88f001b82e884 Mon Sep 17 00:00:00 2001 From: Joachim Schoeberl Date: Wed, 28 Oct 2009 00:04:19 +0000 Subject: [PATCH] quicksort for arrays --- libsrc/general/array.hpp | 1154 ++++++++++++++++++++------------------ 1 file changed, 596 insertions(+), 558 deletions(-) diff --git a/libsrc/general/array.hpp b/libsrc/general/array.hpp index 520f4b73..32e7810a 100644 --- a/libsrc/general/array.hpp +++ b/libsrc/general/array.hpp @@ -11,626 +11,664 @@ namespace netgen { -// template class IndirectArray; + // template class IndirectArray; -/** - A simple array container. - Array represented by size and data-pointer. - No memory allocation and deallocation, must be provided by user. - Helper functions for printing. - Optional range check by macro RANGE_CHECK - */ - -template -class FlatArray -{ -protected: - /// the size - int size; - /// the data - T * data; -public: - - /// provide size and memory - FlatArray (int asize, T * adata) - : size(asize), data(adata) { ; } - - /// the size - int Size() const { return size; } - - int Begin() const { return BASE; } - int End() const { return size+BASE; } - - /* - /// access array. - T & operator[] (int i) - { -#ifdef DEBUG - if (i-BASE < 0 || i-BASE >= size) - cout << "array<" << typeid(T).name() << "> out of range, i = " << i << ", s = " << size << endl; -#endif - - return data[i-BASE]; - } + /** + A simple array container. + Array represented by size and data-pointer. + No memory allocation and deallocation, must be provided by user. + Helper functions for printing. + Optional range check by macro RANGE_CHECK */ - /// Access array. BASE-based - T & operator[] (int i) const + template + class FlatArray { + protected: + /// the size + int size; + /// the data + T * data; + public: + + /// provide size and memory + FlatArray (int asize, T * adata) + : size(asize), data(adata) { ; } + + /// the size + int Size() const { return size; } + + int Begin() const { return BASE; } + int End() const { return size+BASE; } + + /* + /// access array. + T & operator[] (int i) + { + #ifdef DEBUG + if (i-BASE < 0 || i-BASE >= size) + cout << "array<" << typeid(T).name() << "> out of range, i = " << i << ", s = " << size << endl; + #endif + + return data[i-BASE]; + } + */ + + /// Access array. BASE-based + T & operator[] (int i) const + { #ifdef DEBUG - if (i-BASE < 0 || i-BASE >= size) - cout << "array<" << typeid(T).name() << "> out of range, i = " << i << ", s = " << size << endl; + if (i-BASE < 0 || i-BASE >= size) + cout << "array<" << typeid(T).name() << "> out of range, i = " << i << ", s = " << size << endl; #endif - return data[i-BASE]; - } + return data[i-BASE]; + } - /* - template - IndirectArray operator[] (const FlatArray & ind) - { return IndirectArray (*this, ind); } - */ + /* + template + IndirectArray operator[] (const FlatArray & ind) + { return IndirectArray (*this, ind); } + */ - /// Access array, one-based (old fashioned) - T & Elem (int i) - { + /// Access array, one-based (old fashioned) + T & Elem (int i) + { #ifdef DEBUG - if (i < 1 || i > size) - cout << "Array<" << typeid(T).name() - << ">::Elem out of range, i = " << i - << ", s = " << size << endl; + if (i < 1 || i > size) + cout << "Array<" << typeid(T).name() + << ">::Elem out of range, i = " << i + << ", s = " << size << endl; #endif - return ((T*)data)[i-1]; - } + return ((T*)data)[i-1]; + } - /// Access array, one-based (old fashioned) - const T & Get (int i) const - { + /// Access array, one-based (old fashioned) + const T & Get (int i) const + { #ifdef DEBUG - if (i < 1 || i > size) - cout << "Array<" << typeid(T).name() << ">::Get out of range, i = " << i - << ", s = " << size << endl; + if (i < 1 || i > size) + cout << "Array<" << typeid(T).name() << ">::Get out of range, i = " << i + << ", s = " << size << endl; #endif - return ((const T*)data)[i-1]; - } + return ((const T*)data)[i-1]; + } - /// Access array, one-based (old fashioned) - void Set (int i, const T & el) - { + /// Access array, one-based (old fashioned) + void Set (int i, const T & el) + { #ifdef DEBUG - if (i < 1 || i > size) - cout << "Array<" << typeid(T).name() << ">::Set out of range, i = " << i - << ", s = " << size << endl; + if (i < 1 || i > size) + cout << "Array<" << typeid(T).name() << ">::Set out of range, i = " << i + << ", s = " << size << endl; #endif - ((T*)data)[i-1] = el; - } + ((T*)data)[i-1] = el; + } - /// access first element - T & First () const + /// access first element + T & First () const + { + return data[0]; + } + + + /// access last element. check by macro CHECK_RANGE + T & Last () const + { + return data[size-1]; + } + + /// Fill array with value val + FlatArray & operator= (const T & val) + { + for (int i = 0; i < size; i++) + data[i] = val; + return *this; + } + + /// takes range starting from position start of end-start elements + const FlatArray Range (int start, int end) + { + return FlatArray (end-start, data+start); + } + + /// first position of element elem, returns -1 if element not contained in array + int Pos(const T & elem) const + { + int pos = -1; + for(int i=0; pos==-1 && i < this->size; i++) + if(elem == data[i]) pos = i; + return pos; + } + + /// does the array contain element elem ? + bool Contains(const T & elem) const + { + return ( Pos(elem) >= 0 ); + } + }; + + + + // print array + template + inline ostream & operator<< (ostream & s, const FlatArray & a) { - return data[0]; + for (int i = a.Begin(); i < a.End(); i++) + s << i << ": " << a[i] << endl; + return s; } - /// access last element. check by macro CHECK_RANGE - T & Last () const - { - return data[size-1]; - } - /// Fill array with value val - FlatArray & operator= (const T & val) - { - for (int i = 0; i < size; i++) - data[i] = val; - return *this; - } - - /// takes range starting from position start of end-start elements - const FlatArray Range (int start, int end) - { - return FlatArray (end-start, data+start); - } - - /// first position of element elem, returns -1 if element not contained in array - int Pos(const T & elem) const - { - int pos = -1; - for(int i=0; pos==-1 && i < this->size; i++) - if(elem == data[i]) pos = i; - return pos; - } - - /// does the array contain element elem ? - bool Contains(const T & elem) const - { - return ( Pos(elem) >= 0 ); - } -}; - - - -// print array -template -inline ostream & operator<< (ostream & s, const FlatArray & a) -{ - for (int i = a.Begin(); i < a.End(); i++) - s << i << ": " << a[i] << endl; - return s; -} - - - -/** - Dynamic array container. + /** + Dynamic array container. - Array is an automatically increasing array container. - The allocated memory doubles on overflow. - Either the container takes care of memory allocation and deallocation, - or the user provides one block of data. -*/ -template -class Array : public FlatArray -{ -protected: - /// physical size of array - int allocsize; - /// memory is responsibility of container - bool ownmem; - -public: - - /// Generate array of logical and physical size asize - explicit Array(int asize = 0) - : FlatArray (asize, asize ? new T[asize] : 0) + Array is an automatically increasing array container. + The allocated memory doubles on overflow. + Either the container takes care of memory allocation and deallocation, + or the user provides one block of data. + */ + template + class Array : public FlatArray { - allocsize = asize; - ownmem = 1; - } + protected: + /// physical size of array + int allocsize; + /// memory is responsibility of container + bool ownmem; - /// Generate array in user data - Array(int asize, T* adata) - : FlatArray (asize, adata) - { - allocsize = asize; - ownmem = 0; - } + public: - /// array copy - explicit Array (const Array & a2) - : FlatArray (a2.Size(), a2.Size() ? new T[a2.Size()] : 0) - { - allocsize = this->size; - ownmem = 1; - for (int i = BASE; i < this->size+BASE; i++) - (*this)[i] = a2[i]; - } + /// Generate array of logical and physical size asize + explicit Array(int asize = 0) + : FlatArray (asize, asize ? new T[asize] : 0) + { + allocsize = asize; + ownmem = 1; + } + + /// Generate array in user data + Array(int asize, T* adata) + : FlatArray (asize, adata) + { + allocsize = asize; + ownmem = 0; + } + + /// array copy + explicit Array (const Array & a2) + : FlatArray (a2.Size(), a2.Size() ? new T[a2.Size()] : 0) + { + allocsize = this->size; + ownmem = 1; + for (int i = BASE; i < this->size+BASE; i++) + (*this)[i] = a2[i]; + } - /// if responsible, deletes memory - ~Array() - { - if (ownmem) - delete [] this->data; - } + /// if responsible, deletes memory + ~Array() + { + if (ownmem) + delete [] this->data; + } - /// Change logical size. If necessary, do reallocation. Keeps contents. - void SetSize(int nsize) - { - if (nsize > allocsize) - ReSize (nsize); - this->size = nsize; - } + /// Change logical size. If necessary, do reallocation. Keeps contents. + void SetSize(int nsize) + { + if (nsize > allocsize) + ReSize (nsize); + this->size = nsize; + } - /// Change physical size. Keeps logical size. Keeps contents. - void SetAllocSize (int nallocsize) - { - if (nallocsize > allocsize) - ReSize (nallocsize); - } + /// Change physical size. Keeps logical size. Keeps contents. + void SetAllocSize (int nallocsize) + { + if (nallocsize > allocsize) + ReSize (nallocsize); + } - /// Add element at end of array. reallocation if necessary. - int Append (const T & el) - { - if (this->size == allocsize) - ReSize (this->size+1); - this->data[this->size] = el; - this->size++; - return this->size; - } + /// Add element at end of array. reallocation if necessary. + int Append (const T & el) + { + if (this->size == allocsize) + ReSize (this->size+1); + this->data[this->size] = el; + this->size++; + return this->size; + } - template - void Append (FlatArray a2) - { - if (this->size+a2.Size() > allocsize) + template + void Append (FlatArray a2) + { + if (this->size+a2.Size() > allocsize) + ReSize (this->size+a2.Size()); + for (int i = 0; i < a2.Size(); i++) + this->data[this->size+i] = a2[i+B2]; + this->size += a2.Size(); + } + + + /* + template + void Append (const IndirectArray & a2) + { + if (this->size+a2.Size() > allocsize) ReSize (this->size+a2.Size()); - for (int i = 0; i < a2.Size(); i++) + for (int i = 0; i < a2.Size(); i++) this->data[this->size+i] = a2[i+B2]; - this->size += a2.Size(); - } + this->size += a2.Size(); + } + */ + + /// Delete element i (0-based). Move last element to position i. + void Delete (int i) + { +#ifdef CHECK_Array_RANGE + RangeCheck (i+1); +#endif + + this->data[i] = this->data[this->size-1]; + this->size--; + // DeleteElement (i+1); + } + + + /// Delete element i (1-based). Move last element to position i. + void DeleteElement (int i) + { +#ifdef CHECK_Array_RANGE + RangeCheck (i); +#endif + + this->data[i-1] = this->data[this->size-1]; + this->size--; + } + + /// Delete last element. + void DeleteLast () + { + this->size--; + } + + /// Deallocate memory + void DeleteAll () + { + if (ownmem) + delete [] this->data; + this->data = 0; + this->size = allocsize = 0; + } + + /// Fill array with val + Array & operator= (const T & val) + { + FlatArray::operator= (val); + return *this; + } + + /// array copy + Array & operator= (const Array & a2) + { + SetSize (a2.Size()); + for (int i = BASE; i < this->size+BASE; i++) + (*this)[i] = a2[i]; + return *this; + } + + /// array copy + Array & operator= (const FlatArray & a2) + { + SetSize (a2.Size()); + for (int i = BASE; i < this->size+BASE; i++) + (*this)[i] = a2[i]; + return *this; + } + + + private: + + /// resize array, at least to size minsize. copy contents + void ReSize (int minsize) + { + int nsize = 2 * allocsize; + if (nsize < minsize) nsize = minsize; + + if (this->data) + { + T * p = new T[nsize]; + + int mins = (nsize < this->size) ? nsize : this->size; + memcpy (p, this->data, mins * sizeof(T)); + + if (ownmem) + delete [] this->data; + ownmem = 1; + this->data = p; + } + else + { + this->data = new T[nsize]; + ownmem = 1; + } + + allocsize = nsize; + } + }; + + + + template + class ArrayMem : public Array + { + // T mem[S]; // Intel C++ calls dummy constructor + // char mem[S*sizeof(T)]; + double mem[(S*sizeof(T)+7) / 8]; + public: + /// Generate array of logical and physical size asize + explicit ArrayMem(int asize = 0) + : Array (S, static_cast (static_cast(&mem[0]))) + { + this->size = asize; + if (asize > S) + { + this->data = new T[asize]; + this->ownmem = 1; + } + // this->SetSize (asize); + } + + ArrayMem & operator= (const T & val) + { + Array::operator= (val); + return *this; + } + }; + + + /* - template - void Append (const IndirectArray & a2) - { - if (this->size+a2.Size() > allocsize) - ReSize (this->size+a2.Size()); - for (int i = 0; i < a2.Size(); i++) - this->data[this->size+i] = a2[i+B2]; - this->size += a2.Size(); - } + template + class IndirectArray + { + const FlatArray & array; + const FlatArray & ia; + + public: + IndirectArray (const FlatArray & aa, const FlatArray & aia) + : array(aa), ia(aia) { ; } + int Size() const { return ia.Size(); } + const T & operator[] (int i) const { return array[ia[i]]; } + }; */ - /// Delete element i (0-based). Move last element to position i. - void Delete (int i) + + + + + + + + + /// + template + class MoveableArray { -#ifdef CHECK_Array_RANGE - RangeCheck (i+1); -#endif + int size; + int allocsize; + DynamicMem data; - this->data[i] = this->data[this->size-1]; - this->size--; - // DeleteElement (i+1); - } + public: + MoveableArray() + { + size = allocsize = 0; + data.SetName ("MoveableArray"); + } - /// Delete element i (1-based). Move last element to position i. - void DeleteElement (int i) - { -#ifdef CHECK_Array_RANGE - RangeCheck (i); -#endif - - this->data[i-1] = this->data[this->size-1]; - this->size--; - } - - /// Delete last element. - void DeleteLast () - { - this->size--; - } - - /// Deallocate memory - void DeleteAll () - { - if (ownmem) - delete [] this->data; - this->data = 0; - this->size = allocsize = 0; - } - - /// Fill array with val - Array & operator= (const T & val) - { - FlatArray::operator= (val); - return *this; - } - - /// array copy - Array & operator= (const Array & a2) - { - SetSize (a2.Size()); - for (int i = BASE; i < this->size+BASE; i++) - (*this)[i] = a2[i]; - return *this; - } - - /// array copy - Array & operator= (const FlatArray & a2) - { - SetSize (a2.Size()); - for (int i = BASE; i < this->size+BASE; i++) - (*this)[i] = a2[i]; - return *this; - } - - -private: - - /// resize array, at least to size minsize. copy contents - void ReSize (int minsize) - { - int nsize = 2 * allocsize; - if (nsize < minsize) nsize = minsize; - - if (this->data) - { - T * p = new T[nsize]; - - int mins = (nsize < this->size) ? nsize : this->size; - memcpy (p, this->data, mins * sizeof(T)); - - if (ownmem) - delete [] this->data; - ownmem = 1; - this->data = p; - } - else - { - this->data = new T[nsize]; - ownmem = 1; - } - - allocsize = nsize; - } -}; - - - -template -class ArrayMem : public Array -{ - // T mem[S]; // Intel C++ calls dummy constructor - // char mem[S*sizeof(T)]; - double mem[(S*sizeof(T)+7) / 8]; -public: - /// Generate array of logical and physical size asize - explicit ArrayMem(int asize = 0) - : Array (S, static_cast (static_cast(&mem[0]))) - { - this->size = asize; - if (asize > S) - { - this->data = new T[asize]; - this->ownmem = 1; - } - // this->SetSize (asize); - } - - ArrayMem & operator= (const T & val) - { - Array::operator= (val); - return *this; - } -}; - - - - - -/* -template -class IndirectArray -{ - const FlatArray & array; - const FlatArray & ia; - -public: - IndirectArray (const FlatArray & aa, const FlatArray & aia) - : array(aa), ia(aia) { ; } - int Size() const { return ia.Size(); } - const T & operator[] (int i) const { return array[ia[i]]; } -}; -*/ - - - - - - - - - -/// -template -class MoveableArray -{ - int size; - int allocsize; - DynamicMem data; - -public: - - MoveableArray() - { - size = allocsize = 0; - data.SetName ("MoveableArray"); - } - - MoveableArray(int asize) - : size(asize), allocsize(asize), data(asize) - { ; } + MoveableArray(int asize) + : size(asize), allocsize(asize), data(asize) + { ; } - ~MoveableArray () { ; } + ~MoveableArray () { ; } - int Size() const { return size; } + int Size() const { return size; } - void SetSize(int nsize) - { - if (nsize > allocsize) - { - data.ReAlloc (nsize); - allocsize = nsize; - } - size = nsize; - } - - void SetAllocSize (int nallocsize) - { - data.ReAlloc (nallocsize); - allocsize = nallocsize; - } - - /// - T & operator[] (int i) - { return ((T*)data)[i-BASE]; } - - /// - const T & operator[] (int i) const - { return ((const T*)data)[i-BASE]; } - - /// - T & Elem (int i) - { return ((T*)data)[i-1]; } - - /// - const T & Get (int i) const - { return ((const T*)data)[i-1]; } - - /// - void Set (int i, const T & el) - { ((T*)data)[i-1] = el; } - - /// - T & Last () - { return ((T*)data)[size-1]; } - - /// - const T & Last () const - { return ((const T*)data)[size-1]; } - - /// - int Append (const T & el) - { - if (size == allocsize) - { - SetAllocSize (2*allocsize+1); - } - ((T*)data)[size] = el; - size++; - return size; - } - - /// - void Delete (int i) - { - DeleteElement (i+1); - } - - /// - void DeleteElement (int i) - { - ((T*)data)[i-1] = ((T*)data)[size-1]; - size--; - } - - /// - void DeleteLast () - { size--; } - - /// - void DeleteAll () - { - size = allocsize = 0; - data.Free(); - } - - /// - void PrintMemInfo (ostream & ost) const - { - ost << Size() << " elements of size " << sizeof(T) << " = " - << Size() * sizeof(T) << endl; - } - - MoveableArray & operator= (const T & el) - { - for (int i = 0; i < size; i++) - ((T*)data)[i] = el; - return *this; - } - - - MoveableArray & Copy (const MoveableArray & a2) - { - SetSize (a2.Size()); - for (int i = 0; i < this->size; i++) - data[i] = a2.data[i]; - return *this; - } - - /// array copy - MoveableArray & operator= (const MoveableArray & a2) - { - return Copy(a2); - } - - - void SetName (const char * aname) - { - data.SetName(aname); - } -private: - /// - //MoveableArray & operator= (MoveableArray &); //??? - /// - //MoveableArray (const MoveableArray &); //??? -}; - - -template -inline ostream & operator<< (ostream & ost, MoveableArray & a) -{ - for (int i = 0; i < a.Size(); i++) - ost << i << ": " << a[i] << endl; - return ost; -} - - - -/// bubble sort array -template -inline void BubbleSort (const FlatArray & data) -{ - T hv; - for (int i = 0; i < data.Size(); i++) - for (int j = i+1; j < data.Size(); j++) - if (data[i] > data[j]) + void SetSize(int nsize) + { + if (nsize > allocsize) { - hv = data[i]; - data[i] = data[j]; - data[j] = hv; + data.ReAlloc (nsize); + allocsize = nsize; } -} -/// bubble sort array -template -inline void BubbleSort (FlatArray & data, FlatArray & slave) -{ - T hv; - S hvs; - for (int i = 0; i < data.Size(); i++) - for (int j = i+1; j < data.Size(); j++) - if (data[i] > data[j]) + size = nsize; + } + + void SetAllocSize (int nallocsize) + { + data.ReAlloc (nallocsize); + allocsize = nallocsize; + } + + /// + T & operator[] (int i) + { return ((T*)data)[i-BASE]; } + + /// + const T & operator[] (int i) const + { return ((const T*)data)[i-BASE]; } + + /// + T & Elem (int i) + { return ((T*)data)[i-1]; } + + /// + const T & Get (int i) const + { return ((const T*)data)[i-1]; } + + /// + void Set (int i, const T & el) + { ((T*)data)[i-1] = el; } + + /// + T & Last () + { return ((T*)data)[size-1]; } + + /// + const T & Last () const + { return ((const T*)data)[size-1]; } + + /// + int Append (const T & el) + { + if (size == allocsize) { - hv = data[i]; - data[i] = data[j]; - data[j] = hv; - - hvs = slave[i]; - slave[i] = slave[j]; - slave[j] = hvs; + SetAllocSize (2*allocsize+1); } -} + ((T*)data)[size] = el; + size++; + return size; + } + + /// + void Delete (int i) + { + DeleteElement (i+1); + } + + /// + void DeleteElement (int i) + { + ((T*)data)[i-1] = ((T*)data)[size-1]; + size--; + } + + /// + void DeleteLast () + { size--; } + + /// + void DeleteAll () + { + size = allocsize = 0; + data.Free(); + } + + /// + void PrintMemInfo (ostream & ost) const + { + ost << Size() << " elements of size " << sizeof(T) << " = " + << Size() * sizeof(T) << endl; + } + + MoveableArray & operator= (const T & el) + { + for (int i = 0; i < size; i++) + ((T*)data)[i] = el; + return *this; + } -template -void Intersection (const FlatArray & in1, const FlatArray & in2, - Array & out) -{ - out.SetSize(0); - for(int i=0; i -void Intersection (const FlatArray & in1, const FlatArray & in2, const FlatArray & in3, - Array & out) -{ - out.SetSize(0); - for(int i=0; isize; i++) + data[i] = a2.data[i]; + return *this; + } + + /// array copy + MoveableArray & operator= (const MoveableArray & a2) + { + return Copy(a2); + } + + + void SetName (const char * aname) + { + data.SetName(aname); + } + private: + /// + //MoveableArray & operator= (MoveableArray &); //??? + /// + //MoveableArray (const MoveableArray &); //??? + }; + + + template + inline ostream & operator<< (ostream & ost, MoveableArray & a) + { + for (int i = 0; i < a.Size(); i++) + ost << i << ": " << a[i] << endl; + return ost; + } + + + + /// bubble sort array + template + inline void BubbleSort (const FlatArray & data) + { + for (int i = 0; i < data.Size(); i++) + for (int j = i+1; j < data.Size(); j++) + if (data[i] > data[j]) + { + T hv = data[i]; + data[i] = data[j]; + data[j] = hv; + } + } + + /// bubble sort array + template + inline void BubbleSort (FlatArray & data, FlatArray & slave) + { + for (int i = 0; i < data.Size(); i++) + for (int j = i+1; j < data.Size(); j++) + if (data[i] > data[j]) + { + T hv = data[i]; + data[i] = data[j]; + data[j] = hv; + + S hvs = slave[i]; + slave[i] = slave[j]; + slave[j] = hvs; + } + } + + + template + void QickSortRec (FlatArray & data, + FlatArray & slave, + int left, int right) + { + int i = left; + int j = right; + T midval = data[(left+right)/2]; + + do + { + while (data[i] < midval) i++; + while (midval < data[j]) j--; + + if (i <= j) + { + Swap (data[i], data[j]); + Swap (slave[i], slave[j]); + i++; j--; + } + } + while (i <= j); + if (left < j) QickSortRec (data, slave, left, j); + if (i < right) QickSortRec (data, slave, i, right); + } + + template + void QickSort (FlatArray & data, FlatArray & slave) + { + QickSortRec (data, slave, 0, data.Size()-1); + } + + + + + + + + + + template + void Intersection (const FlatArray & in1, const FlatArray & in2, + Array & out) + { + out.SetSize(0); + for(int i=0; i + void Intersection (const FlatArray & in1, const FlatArray & in2, const FlatArray & in3, + Array & out) + { + out.SetSize(0); + for(int i=0; i