//================================================================= // This file is a part of the Minimum Template Library. // By Limin Fu (phoolimin@gmail.com, lmfu@ucsd.edu) // Released under the MIT license. //================================================================= #ifndef __MIN_ARRAY_HXX__ #define __MIN_ARRAY_HXX__ #include #include #include #include #include #include"minBase.hxx" BEGIN_NS_MIN template class Array { item_t *items; item_t *buf; size_t size; size_t bufsize; public: Array( size_t n=0, item_t it=item_t() ){ items = buf = NULL; size = bufsize = 0; Resize( n, it ); } Array( const Array & other ){ items = buf = NULL; size = bufsize = 0; this->operator=( other ); } ~Array(){ Clear(); } size_t Size()const{ return size; } item_t* Data(){ return items; } item_t& operator[]( size_t i ){ return items[i]; } item_t operator[]( size_t i )const{ return items[i]; } Array& operator=( const Array & other ){ size_t i; Clear(); size = other.size; bufsize = other.bufsize; items = buf = (item_t*) calloc( bufsize, sizeof(item_t) ); for(i=0; i bufsize ) Resize( n ); else size = n; } void ResetBuffer(){ // remove buffer from front: if( items == buf ) return; memmove( buf, items, size*sizeof(item_t) ); items = buf; } void Reserve( size_t n, bool extra=false ){ size_t front = (intptr_t) (items - buf); if( bufsize >= (n + front) ) return; // enough space at back if( bufsize >= n ){ // front > 0 ResetBuffer(); return; } void *old = buf; if( extra ) n += n/5; buf = (item_t*) malloc( n*sizeof(item_t) ); memmove( buf, items, size*sizeof(item_t) ); items = buf; bufsize = n; free( old ); } void Resize( size_t n, item_t it=item_t() ){ size_t i; ResetBuffer(); if( bufsize != n ){ items = buf = (item_t*) realloc( buf, n*sizeof(item_t) ); bufsize = n; } for(i=size; i= size ) return; if( n < 0 ) n = size - start; n += start; if( n > size ) n = size; size_t i; for(i=start; i items[i] ){ item_t tmp = items[i-1]; items[i-1] = items[i]; items[i] = tmp; swap = i; } } sorted = swap; } } void QuickSort( size_t partial=0, size_t sub=0 ){ if( size <= 1 ) return; if( partial ==0 ) partial = size; if( sub ==0 ) sub = size; PartialQuickSort( items, 0, sub-1, partial ); } /* Quick Sort. * Adam Drozdek: Data Structures and Algorithms in C++, 2nd Edition. */ void PartialQuickSort( item_t *data, size_t first, size_t last, size_t partial ) { size_t lower=first+1, upper=last; item_t pivot; item_t val; if( first >= last ) return; val = data[first]; data[first] = data[ (first+last)/2 ]; data[ (first+last)/2 ] = val; pivot = data[ first ]; while( lower <= upper ){ while( lower <= last && data[lower] < pivot ) lower ++; while( pivot < data[upper] ) upper --; if( lower < upper ){ val = data[lower]; data[lower] = data[upper]; data[upper] = val; upper --; } lower ++; } val = data[first]; data[first] = data[upper]; data[upper] = val; if( upper && first < upper-1 ) PartialQuickSort( data, first, upper-1, partial ); if( upper >= partial ) return; if( upper+1 < last ) PartialQuickSort( data, upper+1, last, partial ); } item_t QuickXth( item_t *data, size_t first, size_t last, size_t X ) { size_t lower=first+1, upper=last; item_t pivot; item_t val; if( first >= last ) return data[last]; val = data[first]; data[first] = data[ (first+last)/2 ]; data[ (first+last)/2 ] = val; pivot = data[ first ]; while( lower <= upper ){ while( lower <= last && data[lower] < pivot ) lower ++; while( pivot < data[upper] ) upper --; if( lower < upper ){ val = data[lower]; data[lower] = data[upper]; data[upper] = val; upper --; } lower ++; } val = data[first]; data[first] = data[upper]; data[upper] = val; if( first < upper-1 and upper > X ) return QuickXth( data, first, upper-1, X ); if( upper+1 < last and upper < X ) return QuickXth( data, upper+1, last, X ); return val; } item_t QuickMedian(){ Array tmp( *this ); return QuickXth( tmp.items, 0, size-1, size/2 ); } item_t QuickXth( size_t xth ){ Array tmp( *this ); return QuickXth( tmp.items, 0, size-1, xth ); } }; END_NS_MIN #endif